//===-- RuntimeDyldELF.cpp - Run-time dynamic linker for MC-JIT -*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// Implementation of ELF support for the MC-JIT runtime dynamic linker.
//
//===----------------------------------------------------------------------===//

#include "RuntimeDyldELF.h"
#include "Targets/RuntimeDyldELFMips.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/ExecutionEngine/Orc/SymbolStringPool.h"
#include "llvm/Object/ELFObjectFile.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/TargetParser/Triple.h"

using namespace llvm;
using namespace llvm::object;
using namespace llvm::support::endian;

#define DEBUG_TYPE "dyld"

static void or32le(void *P, int32_t V) { write32le(P, read32le(P) | V); }

static void or32AArch64Imm(void *L, uint64_t Imm) {
  or32le(L, (Imm & 0xFFF) << 10);
}

template <class T> static void write(bool isBE, void *P, T V) {
  isBE ? write<T, llvm::endianness::big>(P, V)
       : write<T, llvm::endianness::little>(P, V);
}

static void write32AArch64Addr(void *L, uint64_t Imm) {
  uint32_t ImmLo = (Imm & 0x3) << 29;
  uint32_t ImmHi = (Imm & 0x1FFFFC) << 3;
  uint64_t Mask = (0x3 << 29) | (0x1FFFFC << 3);
  write32le(L, (read32le(L) & ~Mask) | ImmLo | ImmHi);
}

// Return the bits [Start, End] from Val shifted Start bits.
// For instance, getBits(0xF0, 4, 8) returns 0xF.
static uint64_t getBits(uint64_t Val, int Start, int End) {
  uint64_t Mask = ((uint64_t)1 << (End + 1 - Start)) - 1;
  return (Val >> Start) & Mask;
}

namespace {

template <class ELFT> class DyldELFObject : public ELFObjectFile<ELFT> {
  LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)

  typedef typename ELFT::uint addr_type;

  DyldELFObject(ELFObjectFile<ELFT> &&Obj);

public:
  static Expected<std::unique_ptr<DyldELFObject>>
  create(MemoryBufferRef Wrapper);

  void updateSectionAddress(const SectionRef &Sec, uint64_t Addr);

  void updateSymbolAddress(const SymbolRef &SymRef, uint64_t Addr);

  // Methods for type inquiry through isa, cast and dyn_cast
  static bool classof(const Binary *v) {
    return (isa<ELFObjectFile<ELFT>>(v) &&
            classof(cast<ELFObjectFile<ELFT>>(v)));
  }
  static bool classof(const ELFObjectFile<ELFT> *v) {
    return v->isDyldType();
  }
};



// The MemoryBuffer passed into this constructor is just a wrapper around the
// actual memory.  Ultimately, the Binary parent class will take ownership of
// this MemoryBuffer object but not the underlying memory.
template <class ELFT>
DyldELFObject<ELFT>::DyldELFObject(ELFObjectFile<ELFT> &&Obj)
    : ELFObjectFile<ELFT>(std::move(Obj)) {
  this->isDyldELFObject = true;
}

template <class ELFT>
Expected<std::unique_ptr<DyldELFObject<ELFT>>>
DyldELFObject<ELFT>::create(MemoryBufferRef Wrapper) {
  auto Obj = ELFObjectFile<ELFT>::create(Wrapper);
  if (auto E = Obj.takeError())
    return std::move(E);
  std::unique_ptr<DyldELFObject<ELFT>> Ret(
      new DyldELFObject<ELFT>(std::move(*Obj)));
  return std::move(Ret);
}

template <class ELFT>
void DyldELFObject<ELFT>::updateSectionAddress(const SectionRef &Sec,
                                               uint64_t Addr) {
  DataRefImpl ShdrRef = Sec.getRawDataRefImpl();
  Elf_Shdr *shdr =
      const_cast<Elf_Shdr *>(reinterpret_cast<const Elf_Shdr *>(ShdrRef.p));

  // This assumes the address passed in matches the target address bitness
  // The template-based type cast handles everything else.
  shdr->sh_addr = static_cast<addr_type>(Addr);
}

template <class ELFT>
void DyldELFObject<ELFT>::updateSymbolAddress(const SymbolRef &SymRef,
                                              uint64_t Addr) {

  Elf_Sym *sym = const_cast<Elf_Sym *>(
      ELFObjectFile<ELFT>::getSymbol(SymRef.getRawDataRefImpl()));

  // This assumes the address passed in matches the target address bitness
  // The template-based type cast handles everything else.
  sym->st_value = static_cast<addr_type>(Addr);
}

class LoadedELFObjectInfo final
    : public LoadedObjectInfoHelper<LoadedELFObjectInfo,
                                    RuntimeDyld::LoadedObjectInfo> {
public:
  LoadedELFObjectInfo(RuntimeDyldImpl &RTDyld, ObjSectionToIDMap ObjSecToIDMap)
      : LoadedObjectInfoHelper(RTDyld, std::move(ObjSecToIDMap)) {}

  OwningBinary<ObjectFile>
  getObjectForDebug(const ObjectFile &Obj) const override;
};

template <typename ELFT>
static Expected<std::unique_ptr<DyldELFObject<ELFT>>>
createRTDyldELFObject(MemoryBufferRef Buffer, const ObjectFile &SourceObject,
                      const LoadedELFObjectInfo &L) {
  typedef typename ELFT::Shdr Elf_Shdr;
  typedef typename ELFT::uint addr_type;

  Expected<std::unique_ptr<DyldELFObject<ELFT>>> ObjOrErr =
      DyldELFObject<ELFT>::create(Buffer);
  if (Error E = ObjOrErr.takeError())
    return std::move(E);

  std::unique_ptr<DyldELFObject<ELFT>> Obj = std::move(*ObjOrErr);

  // Iterate over all sections in the object.
  auto SI = SourceObject.section_begin();
  for (const auto &Sec : Obj->sections()) {
    Expected<StringRef> NameOrErr = Sec.getName();
    if (!NameOrErr) {
      consumeError(NameOrErr.takeError());
      continue;
    }

    if (*NameOrErr != "") {
      DataRefImpl ShdrRef = Sec.getRawDataRefImpl();
      Elf_Shdr *shdr = const_cast<Elf_Shdr *>(
          reinterpret_cast<const Elf_Shdr *>(ShdrRef.p));

      if (uint64_t SecLoadAddr = L.getSectionLoadAddress(*SI)) {
        // This assumes that the address passed in matches the target address
        // bitness. The template-based type cast handles everything else.
        shdr->sh_addr = static_cast<addr_type>(SecLoadAddr);
      }
    }
    ++SI;
  }

  return std::move(Obj);
}

static OwningBinary<ObjectFile>
createELFDebugObject(const ObjectFile &Obj, const LoadedELFObjectInfo &L) {
  assert(Obj.isELF() && "Not an ELF object file.");

  std::unique_ptr<MemoryBuffer> Buffer =
    MemoryBuffer::getMemBufferCopy(Obj.getData(), Obj.getFileName());

  Expected<std::unique_ptr<ObjectFile>> DebugObj(nullptr);
  handleAllErrors(DebugObj.takeError());
  if (Obj.getBytesInAddress() == 4 && Obj.isLittleEndian())
    DebugObj =
        createRTDyldELFObject<ELF32LE>(Buffer->getMemBufferRef(), Obj, L);
  else if (Obj.getBytesInAddress() == 4 && !Obj.isLittleEndian())
    DebugObj =
        createRTDyldELFObject<ELF32BE>(Buffer->getMemBufferRef(), Obj, L);
  else if (Obj.getBytesInAddress() == 8 && !Obj.isLittleEndian())
    DebugObj =
        createRTDyldELFObject<ELF64BE>(Buffer->getMemBufferRef(), Obj, L);
  else if (Obj.getBytesInAddress() == 8 && Obj.isLittleEndian())
    DebugObj =
        createRTDyldELFObject<ELF64LE>(Buffer->getMemBufferRef(), Obj, L);
  else
    llvm_unreachable("Unexpected ELF format");

  handleAllErrors(DebugObj.takeError());
  return OwningBinary<ObjectFile>(std::move(*DebugObj), std::move(Buffer));
}

OwningBinary<ObjectFile>
LoadedELFObjectInfo::getObjectForDebug(const ObjectFile &Obj) const {
  return createELFDebugObject(Obj, *this);
}

} // anonymous namespace

namespace llvm {

RuntimeDyldELF::RuntimeDyldELF(RuntimeDyld::MemoryManager &MemMgr,
                               JITSymbolResolver &Resolver)
    : RuntimeDyldImpl(MemMgr, Resolver), GOTSectionID(0), CurrentGOTIndex(0) {}
RuntimeDyldELF::~RuntimeDyldELF() = default;

void RuntimeDyldELF::registerEHFrames() {
  for (SID EHFrameSID : UnregisteredEHFrameSections) {
    uint8_t *EHFrameAddr = Sections[EHFrameSID].getAddress();
    uint64_t EHFrameLoadAddr = Sections[EHFrameSID].getLoadAddress();
    size_t EHFrameSize = Sections[EHFrameSID].getSize();
    MemMgr.registerEHFrames(EHFrameAddr, EHFrameLoadAddr, EHFrameSize);
  }
  UnregisteredEHFrameSections.clear();
}

std::unique_ptr<RuntimeDyldELF>
llvm::RuntimeDyldELF::create(Triple::ArchType Arch,
                             RuntimeDyld::MemoryManager &MemMgr,
                             JITSymbolResolver &Resolver) {
  switch (Arch) {
  default:
    return std::make_unique<RuntimeDyldELF>(MemMgr, Resolver);
  case Triple::mips:
  case Triple::mipsel:
  case Triple::mips64:
  case Triple::mips64el:
    return std::make_unique<RuntimeDyldELFMips>(MemMgr, Resolver);
  }
}

std::unique_ptr<RuntimeDyld::LoadedObjectInfo>
RuntimeDyldELF::loadObject(const object::ObjectFile &O) {
  if (auto ObjSectionToIDOrErr = loadObjectImpl(O))
    return std::make_unique<LoadedELFObjectInfo>(*this, *ObjSectionToIDOrErr);
  else {
    HasError = true;
    raw_string_ostream ErrStream(ErrorStr);
    logAllUnhandledErrors(ObjSectionToIDOrErr.takeError(), ErrStream);
    return nullptr;
  }
}

void RuntimeDyldELF::resolveX86_64Relocation(const SectionEntry &Section,
                                             uint64_t Offset, uint64_t Value,
                                             uint32_t Type, int64_t Addend,
                                             uint64_t SymOffset) {
  switch (Type) {
  default:
    report_fatal_error("Relocation type not implemented yet!");
    break;
  case ELF::R_X86_64_NONE:
    break;
  case ELF::R_X86_64_8: {
    Value += Addend;
    assert((int64_t)Value <= INT8_MAX && (int64_t)Value >= INT8_MIN);
    uint8_t TruncatedAddr = (Value & 0xFF);
    *Section.getAddressWithOffset(Offset) = TruncatedAddr;
    LLVM_DEBUG(dbgs() << "Writing " << format("%p", TruncatedAddr) << " at "
                      << format("%p\n", Section.getAddressWithOffset(Offset)));
    break;
  }
  case ELF::R_X86_64_16: {
    Value += Addend;
    assert((int64_t)Value <= INT16_MAX && (int64_t)Value >= INT16_MIN);
    uint16_t TruncatedAddr = (Value & 0xFFFF);
    support::ulittle16_t::ref(Section.getAddressWithOffset(Offset)) =
        TruncatedAddr;
    LLVM_DEBUG(dbgs() << "Writing " << format("%p", TruncatedAddr) << " at "
                      << format("%p\n", Section.getAddressWithOffset(Offset)));
    break;
  }
  case ELF::R_X86_64_64: {
    support::ulittle64_t::ref(Section.getAddressWithOffset(Offset)) =
        Value + Addend;
    LLVM_DEBUG(dbgs() << "Writing " << format("%p", (Value + Addend)) << " at "
                      << format("%p\n", Section.getAddressWithOffset(Offset)));
    break;
  }
  case ELF::R_X86_64_32:
  case ELF::R_X86_64_32S: {
    Value += Addend;
    assert((Type == ELF::R_X86_64_32 && (Value <= UINT32_MAX)) ||
           (Type == ELF::R_X86_64_32S &&
            ((int64_t)Value <= INT32_MAX && (int64_t)Value >= INT32_MIN)));
    uint32_t TruncatedAddr = (Value & 0xFFFFFFFF);
    support::ulittle32_t::ref(Section.getAddressWithOffset(Offset)) =
        TruncatedAddr;
    LLVM_DEBUG(dbgs() << "Writing " << format("%p", TruncatedAddr) << " at "
                      << format("%p\n", Section.getAddressWithOffset(Offset)));
    break;
  }
  case ELF::R_X86_64_PC8: {
    uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
    int64_t RealOffset = Value + Addend - FinalAddress;
    assert(isInt<8>(RealOffset));
    int8_t TruncOffset = (RealOffset & 0xFF);
    Section.getAddress()[Offset] = TruncOffset;
    break;
  }
  case ELF::R_X86_64_PC32: {
    uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
    int64_t RealOffset = Value + Addend - FinalAddress;
    assert(isInt<32>(RealOffset));
    int32_t TruncOffset = (RealOffset & 0xFFFFFFFF);
    support::ulittle32_t::ref(Section.getAddressWithOffset(Offset)) =
        TruncOffset;
    break;
  }
  case ELF::R_X86_64_PC64: {
    uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
    int64_t RealOffset = Value + Addend - FinalAddress;
    support::ulittle64_t::ref(Section.getAddressWithOffset(Offset)) =
        RealOffset;
    LLVM_DEBUG(dbgs() << "Writing " << format("%p", RealOffset) << " at "
                      << format("%p\n", FinalAddress));
    break;
  }
  case ELF::R_X86_64_GOTOFF64: {
    // Compute Value - GOTBase.
    uint64_t GOTBase = 0;
    for (const auto &Section : Sections) {
      if (Section.getName() == ".got") {
        GOTBase = Section.getLoadAddressWithOffset(0);
        break;
      }
    }
    assert(GOTBase != 0 && "missing GOT");
    int64_t GOTOffset = Value - GOTBase + Addend;
    support::ulittle64_t::ref(Section.getAddressWithOffset(Offset)) = GOTOffset;
    break;
  }
  case ELF::R_X86_64_DTPMOD64: {
    // We only have one DSO, so the module id is always 1.
    support::ulittle64_t::ref(Section.getAddressWithOffset(Offset)) = 1;
    break;
  }
  case ELF::R_X86_64_DTPOFF64:
  case ELF::R_X86_64_TPOFF64: {
    // DTPOFF64 should resolve to the offset in the TLS block, TPOFF64 to the
    // offset in the *initial* TLS block. Since we are statically linking, all
    // TLS blocks already exist in the initial block, so resolve both
    // relocations equally.
    support::ulittle64_t::ref(Section.getAddressWithOffset(Offset)) =
        Value + Addend;
    break;
  }
  case ELF::R_X86_64_DTPOFF32:
  case ELF::R_X86_64_TPOFF32: {
    // As for the (D)TPOFF64 relocations above, both DTPOFF32 and TPOFF32 can
    // be resolved equally.
    int64_t RealValue = Value + Addend;
    assert(RealValue >= INT32_MIN && RealValue <= INT32_MAX);
    int32_t TruncValue = RealValue;
    support::ulittle32_t::ref(Section.getAddressWithOffset(Offset)) =
        TruncValue;
    break;
  }
  }
}

void RuntimeDyldELF::resolveX86Relocation(const SectionEntry &Section,
                                          uint64_t Offset, uint32_t Value,
                                          uint32_t Type, int32_t Addend) {
  switch (Type) {
  case ELF::R_386_32: {
    support::ulittle32_t::ref(Section.getAddressWithOffset(Offset)) =
        Value + Addend;
    break;
  }
  // Handle R_386_PLT32 like R_386_PC32 since it should be able to
  // reach any 32 bit address.
  case ELF::R_386_PLT32:
  case ELF::R_386_PC32: {
    uint32_t FinalAddress =
        Section.getLoadAddressWithOffset(Offset) & 0xFFFFFFFF;
    uint32_t RealOffset = Value + Addend - FinalAddress;
    support::ulittle32_t::ref(Section.getAddressWithOffset(Offset)) =
        RealOffset;
    break;
  }
  default:
    // There are other relocation types, but it appears these are the
    // only ones currently used by the LLVM ELF object writer
    report_fatal_error("Relocation type not implemented yet!");
    break;
  }
}

void RuntimeDyldELF::resolveAArch64Relocation(const SectionEntry &Section,
                                              uint64_t Offset, uint64_t Value,
                                              uint32_t Type, int64_t Addend) {
  uint32_t *TargetPtr =
      reinterpret_cast<uint32_t *>(Section.getAddressWithOffset(Offset));
  uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
  // Data should use target endian. Code should always use little endian.
  bool isBE = Arch == Triple::aarch64_be;

  LLVM_DEBUG(dbgs() << "resolveAArch64Relocation, LocalAddress: 0x"
                    << format("%llx", Section.getAddressWithOffset(Offset))
                    << " FinalAddress: 0x" << format("%llx", FinalAddress)
                    << " Value: 0x" << format("%llx", Value) << " Type: 0x"
                    << format("%x", Type) << " Addend: 0x"
                    << format("%llx", Addend) << "\n");

  switch (Type) {
  default:
    report_fatal_error("Relocation type not implemented yet!");
    break;
  case ELF::R_AARCH64_NONE:
    break;
  case ELF::R_AARCH64_ABS16: {
    uint64_t Result = Value + Addend;
    assert(Result == static_cast<uint64_t>(llvm::SignExtend64(Result, 16)) ||
           (Result >> 16) == 0);
    write(isBE, TargetPtr, static_cast<uint16_t>(Result & 0xffffU));
    break;
  }
  case ELF::R_AARCH64_ABS32: {
    uint64_t Result = Value + Addend;
    assert(Result == static_cast<uint64_t>(llvm::SignExtend64(Result, 32)) ||
           (Result >> 32) == 0);
    write(isBE, TargetPtr, static_cast<uint32_t>(Result & 0xffffffffU));
    break;
  }
  case ELF::R_AARCH64_ABS64:
    write(isBE, TargetPtr, Value + Addend);
    break;
  case ELF::R_AARCH64_PLT32: {
    uint64_t Result = Value + Addend - FinalAddress;
    assert(static_cast<int64_t>(Result) >= INT32_MIN &&
           static_cast<int64_t>(Result) <= INT32_MAX);
    write(isBE, TargetPtr, static_cast<uint32_t>(Result));
    break;
  }
  case ELF::R_AARCH64_PREL16: {
    uint64_t Result = Value + Addend - FinalAddress;
    assert(static_cast<int64_t>(Result) >= INT16_MIN &&
           static_cast<int64_t>(Result) <= UINT16_MAX);
    write(isBE, TargetPtr, static_cast<uint16_t>(Result & 0xffffU));
    break;
  }
  case ELF::R_AARCH64_PREL32: {
    uint64_t Result = Value + Addend - FinalAddress;
    assert(static_cast<int64_t>(Result) >= INT32_MIN &&
           static_cast<int64_t>(Result) <= UINT32_MAX);
    write(isBE, TargetPtr, static_cast<uint32_t>(Result & 0xffffffffU));
    break;
  }
  case ELF::R_AARCH64_PREL64:
    write(isBE, TargetPtr, Value + Addend - FinalAddress);
    break;
  case ELF::R_AARCH64_CONDBR19: {
    uint64_t BranchImm = Value + Addend - FinalAddress;

    assert(isInt<21>(BranchImm));
    *TargetPtr &= 0xff00001fU;
    // Immediate:20:2 goes in bits 23:5 of Bcc, CBZ, CBNZ
    or32le(TargetPtr, (BranchImm & 0x001FFFFC) << 3);
    break;
  }
  case ELF::R_AARCH64_TSTBR14: {
    uint64_t BranchImm = Value + Addend - FinalAddress;

    assert(isInt<16>(BranchImm));

    uint32_t RawInstr = *(support::little32_t *)TargetPtr;
    *(support::little32_t *)TargetPtr = RawInstr & 0xfff8001fU;

    // Immediate:15:2 goes in bits 18:5 of TBZ, TBNZ
    or32le(TargetPtr, (BranchImm & 0x0000FFFC) << 3);
    break;
  }
  case ELF::R_AARCH64_CALL26: // fallthrough
  case ELF::R_AARCH64_JUMP26: {
    // Operation: S+A-P. Set Call or B immediate value to bits fff_fffc of the
    // calculation.
    uint64_t BranchImm = Value + Addend - FinalAddress;

    // "Check that -2^27 <= result < 2^27".
    assert(isInt<28>(BranchImm));
    or32le(TargetPtr, (BranchImm & 0x0FFFFFFC) >> 2);
    break;
  }
  case ELF::R_AARCH64_MOVW_UABS_G3:
    or32le(TargetPtr, ((Value + Addend) & 0xFFFF000000000000) >> 43);
    break;
  case ELF::R_AARCH64_MOVW_UABS_G2_NC:
    or32le(TargetPtr, ((Value + Addend) & 0xFFFF00000000) >> 27);
    break;
  case ELF::R_AARCH64_MOVW_UABS_G1_NC:
    or32le(TargetPtr, ((Value + Addend) & 0xFFFF0000) >> 11);
    break;
  case ELF::R_AARCH64_MOVW_UABS_G0_NC:
    or32le(TargetPtr, ((Value + Addend) & 0xFFFF) << 5);
    break;
  case ELF::R_AARCH64_ADR_PREL_PG_HI21: {
    // Operation: Page(S+A) - Page(P)
    uint64_t Result =
        ((Value + Addend) & ~0xfffULL) - (FinalAddress & ~0xfffULL);

    // Check that -2^32 <= X < 2^32
    assert(isInt<33>(Result) && "overflow check failed for relocation");

    // Immediate goes in bits 30:29 + 5:23 of ADRP instruction, taken
    // from bits 32:12 of X.
    write32AArch64Addr(TargetPtr, Result >> 12);
    break;
  }
  case ELF::R_AARCH64_ADD_ABS_LO12_NC:
    // Operation: S + A
    // Immediate goes in bits 21:10 of LD/ST instruction, taken
    // from bits 11:0 of X
    or32AArch64Imm(TargetPtr, Value + Addend);
    break;
  case ELF::R_AARCH64_LDST8_ABS_LO12_NC:
    // Operation: S + A
    // Immediate goes in bits 21:10 of LD/ST instruction, taken
    // from bits 11:0 of X
    or32AArch64Imm(TargetPtr, getBits(Value + Addend, 0, 11));
    break;
  case ELF::R_AARCH64_LDST16_ABS_LO12_NC:
    // Operation: S + A
    // Immediate goes in bits 21:10 of LD/ST instruction, taken
    // from bits 11:1 of X
    or32AArch64Imm(TargetPtr, getBits(Value + Addend, 1, 11));
    break;
  case ELF::R_AARCH64_LDST32_ABS_LO12_NC:
    // Operation: S + A
    // Immediate goes in bits 21:10 of LD/ST instruction, taken
    // from bits 11:2 of X
    or32AArch64Imm(TargetPtr, getBits(Value + Addend, 2, 11));
    break;
  case ELF::R_AARCH64_LDST64_ABS_LO12_NC:
    // Operation: S + A
    // Immediate goes in bits 21:10 of LD/ST instruction, taken
    // from bits 11:3 of X
    or32AArch64Imm(TargetPtr, getBits(Value + Addend, 3, 11));
    break;
  case ELF::R_AARCH64_LDST128_ABS_LO12_NC:
    // Operation: S + A
    // Immediate goes in bits 21:10 of LD/ST instruction, taken
    // from bits 11:4 of X
    or32AArch64Imm(TargetPtr, getBits(Value + Addend, 4, 11));
    break;
  case ELF::R_AARCH64_LD_PREL_LO19: {
    // Operation: S + A - P
    uint64_t Result = Value + Addend - FinalAddress;

    // "Check that -2^20 <= result < 2^20".
    assert(isInt<21>(Result));

    *TargetPtr &= 0xff00001fU;
    // Immediate goes in bits 23:5 of LD imm instruction, taken
    // from bits 20:2 of X
    *TargetPtr |= ((Result & 0xffc) << (5 - 2));
    break;
  }
  case ELF::R_AARCH64_ADR_PREL_LO21: {
    // Operation: S + A - P
    uint64_t Result = Value + Addend - FinalAddress;

    // "Check that -2^20 <= result < 2^20".
    assert(isInt<21>(Result));

    *TargetPtr &= 0x9f00001fU;
    // Immediate goes in bits 23:5, 30:29 of ADR imm instruction, taken
    // from bits 20:0 of X
    *TargetPtr |= ((Result & 0xffc) << (5 - 2));
    *TargetPtr |= (Result & 0x3) << 29;
    break;
  }
  }
}

void RuntimeDyldELF::resolveARMRelocation(const SectionEntry &Section,
                                          uint64_t Offset, uint32_t Value,
                                          uint32_t Type, int32_t Addend) {
  // TODO: Add Thumb relocations.
  uint32_t *TargetPtr =
      reinterpret_cast<uint32_t *>(Section.getAddressWithOffset(Offset));
  uint32_t FinalAddress = Section.getLoadAddressWithOffset(Offset) & 0xFFFFFFFF;
  Value += Addend;

  LLVM_DEBUG(dbgs() << "resolveARMRelocation, LocalAddress: "
                    << Section.getAddressWithOffset(Offset)
                    << " FinalAddress: " << format("%p", FinalAddress)
                    << " Value: " << format("%x", Value)
                    << " Type: " << format("%x", Type)
                    << " Addend: " << format("%x", Addend) << "\n");

  switch (Type) {
  default:
    llvm_unreachable("Not implemented relocation type!");

  case ELF::R_ARM_NONE:
    break;
    // Write a 31bit signed offset
  case ELF::R_ARM_PREL31:
    support::ulittle32_t::ref{TargetPtr} =
        (support::ulittle32_t::ref{TargetPtr} & 0x80000000) |
        ((Value - FinalAddress) & ~0x80000000);
    break;
  case ELF::R_ARM_TARGET1:
  case ELF::R_ARM_ABS32:
    support::ulittle32_t::ref{TargetPtr} = Value;
    break;
    // Write first 16 bit of 32 bit value to the mov instruction.
    // Last 4 bit should be shifted.
  case ELF::R_ARM_MOVW_ABS_NC:
  case ELF::R_ARM_MOVT_ABS:
    if (Type == ELF::R_ARM_MOVW_ABS_NC)
      Value = Value & 0xFFFF;
    else if (Type == ELF::R_ARM_MOVT_ABS)
      Value = (Value >> 16) & 0xFFFF;
    support::ulittle32_t::ref{TargetPtr} =
        (support::ulittle32_t::ref{TargetPtr} & ~0x000F0FFF) | (Value & 0xFFF) |
        (((Value >> 12) & 0xF) << 16);
    break;
    // Write 24 bit relative value to the branch instruction.
  case ELF::R_ARM_PC24: // Fall through.
  case ELF::R_ARM_CALL: // Fall through.
  case ELF::R_ARM_JUMP24:
    int32_t RelValue = static_cast<int32_t>(Value - FinalAddress - 8);
    RelValue = (RelValue & 0x03FFFFFC) >> 2;
    assert((support::ulittle32_t::ref{TargetPtr} & 0xFFFFFF) == 0xFFFFFE);
    support::ulittle32_t::ref{TargetPtr} =
        (support::ulittle32_t::ref{TargetPtr} & 0xFF000000) | RelValue;
    break;
  }
}

bool RuntimeDyldELF::resolveLoongArch64ShortBranch(
    unsigned SectionID, relocation_iterator RelI,
    const RelocationValueRef &Value) {
  uint64_t Address;
  if (Value.SymbolName) {
    auto Loc = GlobalSymbolTable.find(Value.SymbolName);
    // Don't create direct branch for external symbols.
    if (Loc == GlobalSymbolTable.end())
      return false;
    const auto &SymInfo = Loc->second;
    Address =
        uint64_t(Sections[SymInfo.getSectionID()].getLoadAddressWithOffset(
            SymInfo.getOffset()));
  } else {
    Address = uint64_t(Sections[Value.SectionID].getLoadAddress());
  }
  uint64_t Offset = RelI->getOffset();
  uint64_t SourceAddress = Sections[SectionID].getLoadAddressWithOffset(Offset);
  if (!isInt<28>(Address + Value.Addend - SourceAddress))
    return false;
  resolveRelocation(Sections[SectionID], Offset, Address, RelI->getType(),
                    Value.Addend);
  return true;
}

void RuntimeDyldELF::resolveLoongArch64Branch(unsigned SectionID,
                                              const RelocationValueRef &Value,
                                              relocation_iterator RelI,
                                              StubMap &Stubs) {
  LLVM_DEBUG(dbgs() << "\t\tThis is an LoongArch64 branch relocation.\n");

  if (resolveLoongArch64ShortBranch(SectionID, RelI, Value))
    return;

  SectionEntry &Section = Sections[SectionID];
  uint64_t Offset = RelI->getOffset();
  unsigned RelType = RelI->getType();
  // Look for an existing stub.
  StubMap::const_iterator i = Stubs.find(Value);
  if (i != Stubs.end()) {
    resolveRelocation(Section, Offset,
                      (uint64_t)Section.getAddressWithOffset(i->second),
                      RelType, 0);
    LLVM_DEBUG(dbgs() << " Stub function found\n");
    return;
  }
  // Create a new stub function.
  LLVM_DEBUG(dbgs() << " Create a new stub function\n");
  Stubs[Value] = Section.getStubOffset();
  uint8_t *StubTargetAddr =
      createStubFunction(Section.getAddressWithOffset(Section.getStubOffset()));
  RelocationEntry LU12I_W(SectionID, StubTargetAddr - Section.getAddress(),
                          ELF::R_LARCH_ABS_HI20, Value.Addend);
  RelocationEntry ORI(SectionID, StubTargetAddr - Section.getAddress() + 4,
                      ELF::R_LARCH_ABS_LO12, Value.Addend);
  RelocationEntry LU32I_D(SectionID, StubTargetAddr - Section.getAddress() + 8,
                          ELF::R_LARCH_ABS64_LO20, Value.Addend);
  RelocationEntry LU52I_D(SectionID, StubTargetAddr - Section.getAddress() + 12,
                          ELF::R_LARCH_ABS64_HI12, Value.Addend);
  if (Value.SymbolName) {
    addRelocationForSymbol(LU12I_W, Value.SymbolName);
    addRelocationForSymbol(ORI, Value.SymbolName);
    addRelocationForSymbol(LU32I_D, Value.SymbolName);
    addRelocationForSymbol(LU52I_D, Value.SymbolName);
  } else {
    addRelocationForSection(LU12I_W, Value.SectionID);
    addRelocationForSection(ORI, Value.SectionID);
    addRelocationForSection(LU32I_D, Value.SectionID);

    addRelocationForSection(LU52I_D, Value.SectionID);
  }
  resolveRelocation(Section, Offset,
                    reinterpret_cast<uint64_t>(
                        Section.getAddressWithOffset(Section.getStubOffset())),
                    RelType, 0);
  Section.advanceStubOffset(getMaxStubSize());
}

// Returns extract bits Val[Hi:Lo].
static inline uint32_t extractBits(uint64_t Val, uint32_t Hi, uint32_t Lo) {
  return Hi == 63 ? Val >> Lo : (Val & (((1ULL << (Hi + 1)) - 1))) >> Lo;
}

void RuntimeDyldELF::resolveLoongArch64Relocation(const SectionEntry &Section,
                                                  uint64_t Offset,
                                                  uint64_t Value, uint32_t Type,
                                                  int64_t Addend) {
  auto *TargetPtr = Section.getAddressWithOffset(Offset);
  uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);

  LLVM_DEBUG(dbgs() << "resolveLoongArch64Relocation, LocalAddress: 0x"
                    << format("%llx", Section.getAddressWithOffset(Offset))
                    << " FinalAddress: 0x" << format("%llx", FinalAddress)
                    << " Value: 0x" << format("%llx", Value) << " Type: 0x"
                    << format("%x", Type) << " Addend: 0x"
                    << format("%llx", Addend) << "\n");

  switch (Type) {
  default:
    report_fatal_error("Relocation type not implemented yet!");
    break;
  case ELF::R_LARCH_32:
    support::ulittle32_t::ref{TargetPtr} =
        static_cast<uint32_t>(Value + Addend);
    break;
  case ELF::R_LARCH_64:
    support::ulittle64_t::ref{TargetPtr} = Value + Addend;
    break;
  case ELF::R_LARCH_32_PCREL:
    support::ulittle32_t::ref{TargetPtr} =
        static_cast<uint32_t>(Value + Addend - FinalAddress);
    break;
  case ELF::R_LARCH_B26: {
    uint64_t B26 = (Value + Addend - FinalAddress) >> 2;
    auto Instr = support::ulittle32_t::ref(TargetPtr);
    uint32_t Imm15_0 = extractBits(B26, /*Hi=*/15, /*Lo=*/0) << 10;
    uint32_t Imm25_16 = extractBits(B26, /*Hi=*/25, /*Lo=*/16);
    Instr = (Instr & 0xfc000000) | Imm15_0 | Imm25_16;
    break;
  }
  case ELF::R_LARCH_CALL36: {
    uint64_t Call36 = (Value + Addend - FinalAddress) >> 2;
    auto Pcaddu18i = support::ulittle32_t::ref(TargetPtr);
    uint32_t Imm35_16 =
        extractBits((Call36 + (1UL << 15)), /*Hi=*/35, /*Lo=*/16) << 5;
    Pcaddu18i = (Pcaddu18i & 0xfe00001f) | Imm35_16;
    auto Jirl = support::ulittle32_t::ref(TargetPtr + 4);
    uint32_t Imm15_0 = extractBits(Call36, /*Hi=*/15, /*Lo=*/0) << 10;
    Jirl = (Jirl & 0xfc0003ff) | Imm15_0;
    break;
  }
  case ELF::R_LARCH_GOT_PC_HI20:
  case ELF::R_LARCH_PCALA_HI20: {
    uint64_t Target = Value + Addend;
    uint64_t TargetPage =
        (Target + (Target & 0x800)) & ~static_cast<uint64_t>(0xfff);
    uint64_t PCPage = FinalAddress & ~static_cast<uint64_t>(0xfff);
    int64_t PageDelta = TargetPage - PCPage;
    auto Instr = support::ulittle32_t::ref(TargetPtr);
    uint32_t Imm31_12 = extractBits(PageDelta, /*Hi=*/31, /*Lo=*/12) << 5;
    Instr = (Instr & 0xfe00001f) | Imm31_12;
    break;
  }
  case ELF::R_LARCH_GOT_PC_LO12:
  case ELF::R_LARCH_PCALA_LO12: {
    uint64_t TargetOffset = (Value + Addend) & 0xfff;
    auto Instr = support::ulittle32_t::ref(TargetPtr);
    uint32_t Imm11_0 = TargetOffset << 10;
    Instr = (Instr & 0xffc003ff) | Imm11_0;
    break;
  }
  case ELF::R_LARCH_ABS_HI20: {
    uint64_t Target = Value + Addend;
    auto Instr = support::ulittle32_t::ref(TargetPtr);
    uint32_t Imm31_12 = extractBits(Target, /*Hi=*/31, /*Lo=*/12) << 5;
    Instr = (Instr & 0xfe00001f) | Imm31_12;
    break;
  }
  case ELF::R_LARCH_ABS_LO12: {
    uint64_t Target = Value + Addend;
    auto Instr = support::ulittle32_t::ref(TargetPtr);
    uint32_t Imm11_0 = extractBits(Target, /*Hi=*/11, /*Lo=*/0) << 10;
    Instr = (Instr & 0xffc003ff) | Imm11_0;
    break;
  }
  case ELF::R_LARCH_ABS64_LO20: {
    uint64_t Target = Value + Addend;
    auto Instr = support::ulittle32_t::ref(TargetPtr);
    uint32_t Imm51_32 = extractBits(Target, /*Hi=*/51, /*Lo=*/32) << 5;
    Instr = (Instr & 0xfe00001f) | Imm51_32;
    break;
  }
  case ELF::R_LARCH_ABS64_HI12: {
    uint64_t Target = Value + Addend;
    auto Instr = support::ulittle32_t::ref(TargetPtr);
    uint32_t Imm63_52 = extractBits(Target, /*Hi=*/63, /*Lo=*/52) << 10;
    Instr = (Instr & 0xffc003ff) | Imm63_52;
    break;
  }
  case ELF::R_LARCH_ADD32:
    support::ulittle32_t::ref{TargetPtr} =
        (support::ulittle32_t::ref{TargetPtr} +
         static_cast<uint32_t>(Value + Addend));
    break;
  case ELF::R_LARCH_SUB32:
    support::ulittle32_t::ref{TargetPtr} =
        (support::ulittle32_t::ref{TargetPtr} -
         static_cast<uint32_t>(Value + Addend));
    break;
  case ELF::R_LARCH_ADD64:
    support::ulittle64_t::ref{TargetPtr} =
        (support::ulittle64_t::ref{TargetPtr} + Value + Addend);
    break;
  case ELF::R_LARCH_SUB64:
    support::ulittle64_t::ref{TargetPtr} =
        (support::ulittle64_t::ref{TargetPtr} - Value - Addend);
    break;
  }
}

void RuntimeDyldELF::setMipsABI(const ObjectFile &Obj) {
  if (Arch == Triple::UnknownArch ||
      Triple::getArchTypePrefix(Arch) != "mips") {
    IsMipsO32ABI = false;
    IsMipsN32ABI = false;
    IsMipsN64ABI = false;
    return;
  }
  if (auto *E = dyn_cast<ELFObjectFileBase>(&Obj)) {
    unsigned AbiVariant = E->getPlatformFlags();
    IsMipsO32ABI = AbiVariant & ELF::EF_MIPS_ABI_O32;
    IsMipsN32ABI = AbiVariant & ELF::EF_MIPS_ABI2;
  }
  IsMipsN64ABI = Obj.getFileFormatName() == "elf64-mips";
}

// Return the .TOC. section and offset.
Error RuntimeDyldELF::findPPC64TOCSection(const ELFObjectFileBase &Obj,
                                          ObjSectionToIDMap &LocalSections,
                                          RelocationValueRef &Rel) {
  // Set a default SectionID in case we do not find a TOC section below.
  // This may happen for references to TOC base base (sym@toc, .odp
  // relocation) without a .toc directive.  In this case just use the
  // first section (which is usually the .odp) since the code won't
  // reference the .toc base directly.
  Rel.SymbolName = nullptr;
  Rel.SectionID = 0;

  // The TOC consists of sections .got, .toc, .tocbss, .plt in that
  // order. The TOC starts where the first of these sections starts.
  for (auto &Section : Obj.sections()) {
    Expected<StringRef> NameOrErr = Section.getName();
    if (!NameOrErr)
      return NameOrErr.takeError();
    StringRef SectionName = *NameOrErr;

    if (SectionName == ".got"
        || SectionName == ".toc"
        || SectionName == ".tocbss"
        || SectionName == ".plt") {
      if (auto SectionIDOrErr =
            findOrEmitSection(Obj, Section, false, LocalSections))
        Rel.SectionID = *SectionIDOrErr;
      else
        return SectionIDOrErr.takeError();
      break;
    }
  }

  // Per the ppc64-elf-linux ABI, The TOC base is TOC value plus 0x8000
  // thus permitting a full 64 Kbytes segment.
  Rel.Addend = 0x8000;

  return Error::success();
}

// Returns the sections and offset associated with the ODP entry referenced
// by Symbol.
Error RuntimeDyldELF::findOPDEntrySection(const ELFObjectFileBase &Obj,
                                          ObjSectionToIDMap &LocalSections,
                                          RelocationValueRef &Rel) {
  // Get the ELF symbol value (st_value) to compare with Relocation offset in
  // .opd entries
  for (section_iterator si = Obj.section_begin(), se = Obj.section_end();
       si != se; ++si) {

    Expected<section_iterator> RelSecOrErr = si->getRelocatedSection();
    if (!RelSecOrErr)
      report_fatal_error(Twine(toString(RelSecOrErr.takeError())));

    section_iterator RelSecI = *RelSecOrErr;
    if (RelSecI == Obj.section_end())
      continue;

    Expected<StringRef> NameOrErr = RelSecI->getName();
    if (!NameOrErr)
      return NameOrErr.takeError();
    StringRef RelSectionName = *NameOrErr;

    if (RelSectionName != ".opd")
      continue;

    for (elf_relocation_iterator i = si->relocation_begin(),
                                 e = si->relocation_end();
         i != e;) {
      // The R_PPC64_ADDR64 relocation indicates the first field
      // of a .opd entry
      uint64_t TypeFunc = i->getType();
      if (TypeFunc != ELF::R_PPC64_ADDR64) {
        ++i;
        continue;
      }

      uint64_t TargetSymbolOffset = i->getOffset();
      symbol_iterator TargetSymbol = i->getSymbol();
      int64_t Addend;
      if (auto AddendOrErr = i->getAddend())
        Addend = *AddendOrErr;
      else
        return AddendOrErr.takeError();

      ++i;
      if (i == e)
        break;

      // Just check if following relocation is a R_PPC64_TOC
      uint64_t TypeTOC = i->getType();
      if (TypeTOC != ELF::R_PPC64_TOC)
        continue;

      // Finally compares the Symbol value and the target symbol offset
      // to check if this .opd entry refers to the symbol the relocation
      // points to.
      if (Rel.Addend != (int64_t)TargetSymbolOffset)
        continue;

      section_iterator TSI = Obj.section_end();
      if (auto TSIOrErr = TargetSymbol->getSection())
        TSI = *TSIOrErr;
      else
        return TSIOrErr.takeError();
      assert(TSI != Obj.section_end() && "TSI should refer to a valid section");

      bool IsCode = TSI->isText();
      if (auto SectionIDOrErr = findOrEmitSection(Obj, *TSI, IsCode,
                                                  LocalSections))
        Rel.SectionID = *SectionIDOrErr;
      else
        return SectionIDOrErr.takeError();
      Rel.Addend = (intptr_t)Addend;
      return Error::success();
    }
  }
  llvm_unreachable("Attempting to get address of ODP entry!");
}

// Relocation masks following the #lo(value), #hi(value), #ha(value),
// #higher(value), #highera(value), #highest(value), and #highesta(value)
// macros defined in section 4.5.1. Relocation Types of the PPC-elf64abi
// document.

static inline uint16_t applyPPClo(uint64_t value) { return value & 0xffff; }

static inline uint16_t applyPPChi(uint64_t value) {
  return (value >> 16) & 0xffff;
}

static inline uint16_t applyPPCha (uint64_t value) {
  return ((value + 0x8000) >> 16) & 0xffff;
}

static inline uint16_t applyPPChigher(uint64_t value) {
  return (value >> 32) & 0xffff;
}

static inline uint16_t applyPPChighera (uint64_t value) {
  return ((value + 0x8000) >> 32) & 0xffff;
}

static inline uint16_t applyPPChighest(uint64_t value) {
  return (value >> 48) & 0xffff;
}

static inline uint16_t applyPPChighesta (uint64_t value) {
  return ((value + 0x8000) >> 48) & 0xffff;
}

void RuntimeDyldELF::resolvePPC32Relocation(const SectionEntry &Section,
                                            uint64_t Offset, uint64_t Value,
                                            uint32_t Type, int64_t Addend) {
  uint8_t *LocalAddress = Section.getAddressWithOffset(Offset);
  switch (Type) {
  default:
    report_fatal_error("Relocation type not implemented yet!");
    break;
  case ELF::R_PPC_ADDR16_LO:
    writeInt16BE(LocalAddress, applyPPClo(Value + Addend));
    break;
  case ELF::R_PPC_ADDR16_HI:
    writeInt16BE(LocalAddress, applyPPChi(Value + Addend));
    break;
  case ELF::R_PPC_ADDR16_HA:
    writeInt16BE(LocalAddress, applyPPCha(Value + Addend));
    break;
  }
}

void RuntimeDyldELF::resolvePPC64Relocation(const SectionEntry &Section,
                                            uint64_t Offset, uint64_t Value,
                                            uint32_t Type, int64_t Addend) {
  uint8_t *LocalAddress = Section.getAddressWithOffset(Offset);
  switch (Type) {
  default:
    report_fatal_error("Relocation type not implemented yet!");
    break;
  case ELF::R_PPC64_ADDR16:
    writeInt16BE(LocalAddress, applyPPClo(Value + Addend));
    break;
  case ELF::R_PPC64_ADDR16_DS:
    writeInt16BE(LocalAddress, applyPPClo(Value + Addend) & ~3);
    break;
  case ELF::R_PPC64_ADDR16_LO:
    writeInt16BE(LocalAddress, applyPPClo(Value + Addend));
    break;
  case ELF::R_PPC64_ADDR16_LO_DS:
    writeInt16BE(LocalAddress, applyPPClo(Value + Addend) & ~3);
    break;
  case ELF::R_PPC64_ADDR16_HI:
  case ELF::R_PPC64_ADDR16_HIGH:
    writeInt16BE(LocalAddress, applyPPChi(Value + Addend));
    break;
  case ELF::R_PPC64_ADDR16_HA:
  case ELF::R_PPC64_ADDR16_HIGHA:
    writeInt16BE(LocalAddress, applyPPCha(Value + Addend));
    break;
  case ELF::R_PPC64_ADDR16_HIGHER:
    writeInt16BE(LocalAddress, applyPPChigher(Value + Addend));
    break;
  case ELF::R_PPC64_ADDR16_HIGHERA:
    writeInt16BE(LocalAddress, applyPPChighera(Value + Addend));
    break;
  case ELF::R_PPC64_ADDR16_HIGHEST:
    writeInt16BE(LocalAddress, applyPPChighest(Value + Addend));
    break;
  case ELF::R_PPC64_ADDR16_HIGHESTA:
    writeInt16BE(LocalAddress, applyPPChighesta(Value + Addend));
    break;
  case ELF::R_PPC64_ADDR14: {
    assert(((Value + Addend) & 3) == 0);
    // Preserve the AA/LK bits in the branch instruction
    uint8_t aalk = *(LocalAddress + 3);
    writeInt16BE(LocalAddress + 2, (aalk & 3) | ((Value + Addend) & 0xfffc));
  } break;
  case ELF::R_PPC64_REL16_LO: {
    uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
    uint64_t Delta = Value - FinalAddress + Addend;
    writeInt16BE(LocalAddress, applyPPClo(Delta));
  } break;
  case ELF::R_PPC64_REL16_HI: {
    uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
    uint64_t Delta = Value - FinalAddress + Addend;
    writeInt16BE(LocalAddress, applyPPChi(Delta));
  } break;
  case ELF::R_PPC64_REL16_HA: {
    uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
    uint64_t Delta = Value - FinalAddress + Addend;
    writeInt16BE(LocalAddress, applyPPCha(Delta));
  } break;
  case ELF::R_PPC64_ADDR32: {
    int64_t Result = static_cast<int64_t>(Value + Addend);
    if (SignExtend64<32>(Result) != Result)
      llvm_unreachable("Relocation R_PPC64_ADDR32 overflow");
    writeInt32BE(LocalAddress, Result);
  } break;
  case ELF::R_PPC64_REL24: {
    uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
    int64_t delta = static_cast<int64_t>(Value - FinalAddress + Addend);
    if (SignExtend64<26>(delta) != delta)
      llvm_unreachable("Relocation R_PPC64_REL24 overflow");
    // We preserve bits other than LI field, i.e. PO and AA/LK fields.
    uint32_t Inst = readBytesUnaligned(LocalAddress, 4);
    writeInt32BE(LocalAddress, (Inst & 0xFC000003) | (delta & 0x03FFFFFC));
  } break;
  case ELF::R_PPC64_REL32: {
    uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
    int64_t delta = static_cast<int64_t>(Value - FinalAddress + Addend);
    if (SignExtend64<32>(delta) != delta)
      llvm_unreachable("Relocation R_PPC64_REL32 overflow");
    writeInt32BE(LocalAddress, delta);
  } break;
  case ELF::R_PPC64_REL64: {
    uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
    uint64_t Delta = Value - FinalAddress + Addend;
    writeInt64BE(LocalAddress, Delta);
  } break;
  case ELF::R_PPC64_ADDR64:
    writeInt64BE(LocalAddress, Value + Addend);
    break;
  }
}

void RuntimeDyldELF::resolveSystemZRelocation(const SectionEntry &Section,
                                              uint64_t Offset, uint64_t Value,
                                              uint32_t Type, int64_t Addend) {
  uint8_t *LocalAddress = Section.getAddressWithOffset(Offset);
  switch (Type) {
  default:
    report_fatal_error("Relocation type not implemented yet!");
    break;
  case ELF::R_390_PC16DBL:
  case ELF::R_390_PLT16DBL: {
    int64_t Delta = (Value + Addend) - Section.getLoadAddressWithOffset(Offset);
    assert(int16_t(Delta / 2) * 2 == Delta && "R_390_PC16DBL overflow");
    writeInt16BE(LocalAddress, Delta / 2);
    break;
  }
  case ELF::R_390_PC32DBL:
  case ELF::R_390_PLT32DBL: {
    int64_t Delta = (Value + Addend) - Section.getLoadAddressWithOffset(Offset);
    assert(int32_t(Delta / 2) * 2 == Delta && "R_390_PC32DBL overflow");
    writeInt32BE(LocalAddress, Delta / 2);
    break;
  }
  case ELF::R_390_PC16: {
    int64_t Delta = (Value + Addend) - Section.getLoadAddressWithOffset(Offset);
    assert(int16_t(Delta) == Delta && "R_390_PC16 overflow");
    writeInt16BE(LocalAddress, Delta);
    break;
  }
  case ELF::R_390_PC32: {
    int64_t Delta = (Value + Addend) - Section.getLoadAddressWithOffset(Offset);
    assert(int32_t(Delta) == Delta && "R_390_PC32 overflow");
    writeInt32BE(LocalAddress, Delta);
    break;
  }
  case ELF::R_390_PC64: {
    int64_t Delta = (Value + Addend) - Section.getLoadAddressWithOffset(Offset);
    writeInt64BE(LocalAddress, Delta);
    break;
  }
  case ELF::R_390_8:
    *LocalAddress = (uint8_t)(Value + Addend);
    break;
  case ELF::R_390_16:
    writeInt16BE(LocalAddress, Value + Addend);
    break;
  case ELF::R_390_32:
    writeInt32BE(LocalAddress, Value + Addend);
    break;
  case ELF::R_390_64:
    writeInt64BE(LocalAddress, Value + Addend);
    break;
  }
}

void RuntimeDyldELF::resolveBPFRelocation(const SectionEntry &Section,
                                          uint64_t Offset, uint64_t Value,
                                          uint32_t Type, int64_t Addend) {
  bool isBE = Arch == Triple::bpfeb;

  switch (Type) {
  default:
    report_fatal_error("Relocation type not implemented yet!");
    break;
  case ELF::R_BPF_NONE:
  case ELF::R_BPF_64_64:
  case ELF::R_BPF_64_32:
  case ELF::R_BPF_64_NODYLD32:
    break;
  case ELF::R_BPF_64_ABS64: {
    write(isBE, Section.getAddressWithOffset(Offset), Value + Addend);
    LLVM_DEBUG(dbgs() << "Writing " << format("%p", (Value + Addend)) << " at "
                      << format("%p\n", Section.getAddressWithOffset(Offset)));
    break;
  }
  case ELF::R_BPF_64_ABS32: {
    Value += Addend;
    assert(Value <= UINT32_MAX);
    write(isBE, Section.getAddressWithOffset(Offset), static_cast<uint32_t>(Value));
    LLVM_DEBUG(dbgs() << "Writing " << format("%p", Value) << " at "
                      << format("%p\n", Section.getAddressWithOffset(Offset)));
    break;
  }
  }
}

static void applyUTypeImmRISCV(uint8_t *InstrAddr, uint32_t Imm) {
  uint32_t UpperImm = (Imm + 0x800) & 0xfffff000;
  auto Instr = support::ulittle32_t::ref(InstrAddr);
  Instr = (Instr & 0xfff) | UpperImm;
}

static void applyITypeImmRISCV(uint8_t *InstrAddr, uint32_t Imm) {
  uint32_t LowerImm = Imm & 0xfff;
  auto Instr = support::ulittle32_t::ref(InstrAddr);
  Instr = (Instr & 0xfffff) | (LowerImm << 20);
}

void RuntimeDyldELF::resolveRISCVRelocation(const SectionEntry &Section,
                                            uint64_t Offset, uint64_t Value,
                                            uint32_t Type, int64_t Addend,
                                            SID SectionID) {
  switch (Type) {
  default: {
    std::string Err = "Unimplemented reloc type: " + std::to_string(Type);
    llvm::report_fatal_error(Err.c_str());
  }
    // 32-bit PC-relative function call, macros call, tail (PIC)
    // Write first 20 bits of 32 bit value to the auipc instruction
    // Last 12 bits to the jalr instruction
  case ELF::R_RISCV_CALL:
  case ELF::R_RISCV_CALL_PLT: {
    uint64_t P = Section.getLoadAddressWithOffset(Offset);
    uint64_t PCOffset = Value + Addend - P;
    applyUTypeImmRISCV(Section.getAddressWithOffset(Offset), PCOffset);
    applyITypeImmRISCV(Section.getAddressWithOffset(Offset + 4), PCOffset);
    break;
  }
    // High 20 bits of 32-bit absolute address, %hi(symbol)
  case ELF::R_RISCV_HI20: {
    uint64_t PCOffset = Value + Addend;
    applyUTypeImmRISCV(Section.getAddressWithOffset(Offset), PCOffset);
    break;
  }
    // Low 12 bits of 32-bit absolute address, %lo(symbol)
  case ELF::R_RISCV_LO12_I: {
    uint64_t PCOffset = Value + Addend;
    applyITypeImmRISCV(Section.getAddressWithOffset(Offset), PCOffset);
    break;
  }
    // High 20 bits of 32-bit PC-relative reference, %pcrel_hi(symbol)
  case ELF::R_RISCV_GOT_HI20:
  case ELF::R_RISCV_PCREL_HI20: {
    uint64_t P = Section.getLoadAddressWithOffset(Offset);
    uint64_t PCOffset = Value + Addend - P;
    applyUTypeImmRISCV(Section.getAddressWithOffset(Offset), PCOffset);
    break;
  }

    // label:
    //    auipc      a0, %pcrel_hi(symbol)    // R_RISCV_PCREL_HI20
    //    addi       a0, a0, %pcrel_lo(label) // R_RISCV_PCREL_LO12_I
    //
    // The low 12 bits of relative address between pc and symbol.
    // The symbol is related to the high part instruction which is marked by
    // label.
  case ELF::R_RISCV_PCREL_LO12_I: {
    for (auto &&PendingReloc : PendingRelocs) {
      const RelocationValueRef &MatchingValue = PendingReloc.first;
      RelocationEntry &Reloc = PendingReloc.second;
      uint64_t HIRelocPC =
          getSectionLoadAddress(Reloc.SectionID) + Reloc.Offset;
      if (Value + Addend == HIRelocPC) {
        uint64_t Symbol = getSectionLoadAddress(MatchingValue.SectionID) +
                          MatchingValue.Addend;
        auto PCOffset = Symbol - HIRelocPC;
        applyITypeImmRISCV(Section.getAddressWithOffset(Offset), PCOffset);
        return;
      }
    }

    llvm::report_fatal_error(
        "R_RISCV_PCREL_LO12_I without matching R_RISCV_PCREL_HI20");
  }
  case ELF::R_RISCV_32_PCREL: {
    uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
    int64_t RealOffset = Value + Addend - FinalAddress;
    int32_t TruncOffset = Lo_32(RealOffset);
    support::ulittle32_t::ref(Section.getAddressWithOffset(Offset)) =
        TruncOffset;
    break;
  }
  case ELF::R_RISCV_32: {
    auto Ref = support::ulittle32_t::ref(Section.getAddressWithOffset(Offset));
    Ref = Value + Addend;
    break;
  }
  case ELF::R_RISCV_64: {
    auto Ref = support::ulittle64_t::ref(Section.getAddressWithOffset(Offset));
    Ref = Value + Addend;
    break;
  }
  case ELF::R_RISCV_ADD16: {
    auto Ref = support::ulittle16_t::ref(Section.getAddressWithOffset(Offset));
    Ref = Ref + Value + Addend;
    break;
  }
  case ELF::R_RISCV_ADD32: {
    auto Ref = support::ulittle32_t::ref(Section.getAddressWithOffset(Offset));
    Ref = Ref + Value + Addend;
    break;
  }
  case ELF::R_RISCV_ADD64: {
    auto Ref = support::ulittle64_t::ref(Section.getAddressWithOffset(Offset));
    Ref = Ref + Value + Addend;
    break;
  }
  case ELF::R_RISCV_SUB16: {
    auto Ref = support::ulittle16_t::ref(Section.getAddressWithOffset(Offset));
    Ref = Ref - Value - Addend;
    break;
  }
  case ELF::R_RISCV_SUB32: {
    auto Ref = support::ulittle32_t::ref(Section.getAddressWithOffset(Offset));
    Ref = Ref - Value - Addend;
    break;
  }
  case ELF::R_RISCV_SUB64: {
    auto Ref = support::ulittle64_t::ref(Section.getAddressWithOffset(Offset));
    Ref = Ref - Value - Addend;
    break;
  }
  }
}

// The target location for the relocation is described by RE.SectionID and
// RE.Offset.  RE.SectionID can be used to find the SectionEntry.  Each
// SectionEntry has three members describing its location.
// SectionEntry::Address is the address at which the section has been loaded
// into memory in the current (host) process.  SectionEntry::LoadAddress is the
// address that the section will have in the target process.
// SectionEntry::ObjAddress is the address of the bits for this section in the
// original emitted object image (also in the current address space).
//
// Relocations will be applied as if the section were loaded at
// SectionEntry::LoadAddress, but they will be applied at an address based
// on SectionEntry::Address.  SectionEntry::ObjAddress will be used to refer to
// Target memory contents if they are required for value calculations.
//
// The Value parameter here is the load address of the symbol for the
// relocation to be applied.  For relocations which refer to symbols in the
// current object Value will be the LoadAddress of the section in which
// the symbol resides (RE.Addend provides additional information about the
// symbol location).  For external symbols, Value will be the address of the
// symbol in the target address space.
void RuntimeDyldELF::resolveRelocation(const RelocationEntry &RE,
                                       uint64_t Value) {
  const SectionEntry &Section = Sections[RE.SectionID];
  return resolveRelocation(Section, RE.Offset, Value, RE.RelType, RE.Addend,
                           RE.SymOffset, RE.SectionID);
}

void RuntimeDyldELF::resolveRelocation(const SectionEntry &Section,
                                       uint64_t Offset, uint64_t Value,
                                       uint32_t Type, int64_t Addend,
                                       uint64_t SymOffset, SID SectionID) {
  switch (Arch) {
  case Triple::x86_64:
    resolveX86_64Relocation(Section, Offset, Value, Type, Addend, SymOffset);
    break;
  case Triple::x86:
    resolveX86Relocation(Section, Offset, (uint32_t)(Value & 0xffffffffL), Type,
                         (uint32_t)(Addend & 0xffffffffL));
    break;
  case Triple::aarch64:
  case Triple::aarch64_be:
    resolveAArch64Relocation(Section, Offset, Value, Type, Addend);
    break;
  case Triple::arm: // Fall through.
  case Triple::armeb:
  case Triple::thumb:
  case Triple::thumbeb:
    resolveARMRelocation(Section, Offset, (uint32_t)(Value & 0xffffffffL), Type,
                         (uint32_t)(Addend & 0xffffffffL));
    break;
  case Triple::loongarch64:
    resolveLoongArch64Relocation(Section, Offset, Value, Type, Addend);
    break;
  case Triple::ppc: // Fall through.
  case Triple::ppcle:
    resolvePPC32Relocation(Section, Offset, Value, Type, Addend);
    break;
  case Triple::ppc64: // Fall through.
  case Triple::ppc64le:
    resolvePPC64Relocation(Section, Offset, Value, Type, Addend);
    break;
  case Triple::systemz:
    resolveSystemZRelocation(Section, Offset, Value, Type, Addend);
    break;
  case Triple::bpfel:
  case Triple::bpfeb:
    resolveBPFRelocation(Section, Offset, Value, Type, Addend);
    break;
  case Triple::riscv32: // Fall through.
  case Triple::riscv64:
    resolveRISCVRelocation(Section, Offset, Value, Type, Addend, SectionID);
    break;
  default:
    llvm_unreachable("Unsupported CPU type!");
  }
}

void *RuntimeDyldELF::computePlaceholderAddress(unsigned SectionID,
                                                uint64_t Offset) const {
  return (void *)(Sections[SectionID].getObjAddress() + Offset);
}

void RuntimeDyldELF::processSimpleRelocation(unsigned SectionID, uint64_t Offset, unsigned RelType, RelocationValueRef Value) {
  RelocationEntry RE(SectionID, Offset, RelType, Value.Addend, Value.Offset);
  if (Value.SymbolName)
    addRelocationForSymbol(RE, Value.SymbolName);
  else
    addRelocationForSection(RE, Value.SectionID);
}

uint32_t RuntimeDyldELF::getMatchingLoRelocation(uint32_t RelType,
                                                 bool IsLocal) const {
  switch (RelType) {
  case ELF::R_MICROMIPS_GOT16:
    if (IsLocal)
      return ELF::R_MICROMIPS_LO16;
    break;
  case ELF::R_MICROMIPS_HI16:
    return ELF::R_MICROMIPS_LO16;
  case ELF::R_MIPS_GOT16:
    if (IsLocal)
      return ELF::R_MIPS_LO16;
    break;
  case ELF::R_MIPS_HI16:
    return ELF::R_MIPS_LO16;
  case ELF::R_MIPS_PCHI16:
    return ELF::R_MIPS_PCLO16;
  default:
    break;
  }
  return ELF::R_MIPS_NONE;
}

// Sometimes we don't need to create thunk for a branch.
// This typically happens when branch target is located
// in the same object file. In such case target is either
// a weak symbol or symbol in a different executable section.
// This function checks if branch target is located in the
// same object file and if distance between source and target
// fits R_AARCH64_CALL26 relocation. If both conditions are
// met, it emits direct jump to the target and returns true.
// Otherwise false is returned and thunk is created.
bool RuntimeDyldELF::resolveAArch64ShortBranch(
    unsigned SectionID, relocation_iterator RelI,
    const RelocationValueRef &Value) {
  uint64_t TargetOffset;
  unsigned TargetSectionID;
  if (Value.SymbolName) {
    auto Loc = GlobalSymbolTable.find(Value.SymbolName);

    // Don't create direct branch for external symbols.
    if (Loc == GlobalSymbolTable.end())
      return false;

    const auto &SymInfo = Loc->second;

    TargetSectionID = SymInfo.getSectionID();
    TargetOffset = SymInfo.getOffset();
  } else {
    TargetSectionID = Value.SectionID;
    TargetOffset = 0;
  }

  // We don't actually know the load addresses at this point, so if the
  // branch is cross-section, we don't know exactly how far away it is.
  if (TargetSectionID != SectionID)
    return false;

  uint64_t SourceOffset = RelI->getOffset();

  // R_AARCH64_CALL26 requires immediate to be in range -2^27 <= imm < 2^27
  // If distance between source and target is out of range then we should
  // create thunk.
  if (!isInt<28>(TargetOffset + Value.Addend - SourceOffset))
    return false;

  RelocationEntry RE(SectionID, SourceOffset, RelI->getType(), Value.Addend);
  if (Value.SymbolName)
    addRelocationForSymbol(RE, Value.SymbolName);
  else
    addRelocationForSection(RE, Value.SectionID);

  return true;
}

void RuntimeDyldELF::resolveAArch64Branch(unsigned SectionID,
                                          const RelocationValueRef &Value,
                                          relocation_iterator RelI,
                                          StubMap &Stubs) {

  LLVM_DEBUG(dbgs() << "\t\tThis is an AArch64 branch relocation.");
  SectionEntry &Section = Sections[SectionID];

  uint64_t Offset = RelI->getOffset();
  unsigned RelType = RelI->getType();
  // Look for an existing stub.
  StubMap::const_iterator i = Stubs.find(Value);
  if (i != Stubs.end()) {
    resolveRelocation(Section, Offset,
                      Section.getLoadAddressWithOffset(i->second), RelType, 0);
    LLVM_DEBUG(dbgs() << " Stub function found\n");
  } else if (!resolveAArch64ShortBranch(SectionID, RelI, Value)) {
    // Create a new stub function.
    LLVM_DEBUG(dbgs() << " Create a new stub function\n");
    Stubs[Value] = Section.getStubOffset();
    uint8_t *StubTargetAddr = createStubFunction(
        Section.getAddressWithOffset(Section.getStubOffset()));

    RelocationEntry REmovz_g3(SectionID, StubTargetAddr - Section.getAddress(),
                              ELF::R_AARCH64_MOVW_UABS_G3, Value.Addend);
    RelocationEntry REmovk_g2(SectionID,
                              StubTargetAddr - Section.getAddress() + 4,
                              ELF::R_AARCH64_MOVW_UABS_G2_NC, Value.Addend);
    RelocationEntry REmovk_g1(SectionID,
                              StubTargetAddr - Section.getAddress() + 8,
                              ELF::R_AARCH64_MOVW_UABS_G1_NC, Value.Addend);
    RelocationEntry REmovk_g0(SectionID,
                              StubTargetAddr - Section.getAddress() + 12,
                              ELF::R_AARCH64_MOVW_UABS_G0_NC, Value.Addend);

    if (Value.SymbolName) {
      addRelocationForSymbol(REmovz_g3, Value.SymbolName);
      addRelocationForSymbol(REmovk_g2, Value.SymbolName);
      addRelocationForSymbol(REmovk_g1, Value.SymbolName);
      addRelocationForSymbol(REmovk_g0, Value.SymbolName);
    } else {
      addRelocationForSection(REmovz_g3, Value.SectionID);
      addRelocationForSection(REmovk_g2, Value.SectionID);
      addRelocationForSection(REmovk_g1, Value.SectionID);
      addRelocationForSection(REmovk_g0, Value.SectionID);
    }
    resolveRelocation(Section, Offset,
                      Section.getLoadAddressWithOffset(Section.getStubOffset()),
                      RelType, 0);
    Section.advanceStubOffset(getMaxStubSize());
  }
}

Expected<relocation_iterator>
RuntimeDyldELF::processRelocationRef(
    unsigned SectionID, relocation_iterator RelI, const ObjectFile &O,
    ObjSectionToIDMap &ObjSectionToID, StubMap &Stubs) {
  const auto &Obj = cast<ELFObjectFileBase>(O);
  uint64_t RelType = RelI->getType();
  int64_t Addend = 0;
  if (Expected<int64_t> AddendOrErr = ELFRelocationRef(*RelI).getAddend())
    Addend = *AddendOrErr;
  else
    consumeError(AddendOrErr.takeError());
  elf_symbol_iterator Symbol = RelI->getSymbol();

  // Obtain the symbol name which is referenced in the relocation
  StringRef TargetName;
  if (Symbol != Obj.symbol_end()) {
    if (auto TargetNameOrErr = Symbol->getName())
      TargetName = *TargetNameOrErr;
    else
      return TargetNameOrErr.takeError();
  }
  LLVM_DEBUG(dbgs() << "\t\tRelType: " << RelType << " Addend: " << Addend
                    << " TargetName: " << TargetName << "\n");
  RelocationValueRef Value;
  // First search for the symbol in the local symbol table
  SymbolRef::Type SymType = SymbolRef::ST_Unknown;

  // Search for the symbol in the global symbol table
  RTDyldSymbolTable::const_iterator gsi = GlobalSymbolTable.end();
  if (Symbol != Obj.symbol_end()) {
    gsi = GlobalSymbolTable.find(TargetName.data());
    Expected<SymbolRef::Type> SymTypeOrErr = Symbol->getType();
    if (!SymTypeOrErr) {
      std::string Buf;
      raw_string_ostream OS(Buf);
      logAllUnhandledErrors(SymTypeOrErr.takeError(), OS);
      report_fatal_error(Twine(Buf));
    }
    SymType = *SymTypeOrErr;
  }
  if (gsi != GlobalSymbolTable.end()) {
    const auto &SymInfo = gsi->second;
    Value.SectionID = SymInfo.getSectionID();
    Value.Offset = SymInfo.getOffset();
    Value.Addend = SymInfo.getOffset() + Addend;
  } else {
    switch (SymType) {
    case SymbolRef::ST_Debug: {
      // TODO: Now ELF SymbolRef::ST_Debug = STT_SECTION, it's not obviously
      // and can be changed by another developers. Maybe best way is add
      // a new symbol type ST_Section to SymbolRef and use it.
      auto SectionOrErr = Symbol->getSection();
      if (!SectionOrErr) {
        std::string Buf;
        raw_string_ostream OS(Buf);
        logAllUnhandledErrors(SectionOrErr.takeError(), OS);
        report_fatal_error(Twine(Buf));
      }
      section_iterator si = *SectionOrErr;
      if (si == Obj.section_end())
        llvm_unreachable("Symbol section not found, bad object file format!");
      LLVM_DEBUG(dbgs() << "\t\tThis is section symbol\n");
      bool isCode = si->isText();
      if (auto SectionIDOrErr = findOrEmitSection(Obj, (*si), isCode,
                                                  ObjSectionToID))
        Value.SectionID = *SectionIDOrErr;
      else
        return SectionIDOrErr.takeError();
      Value.Addend = Addend;
      break;
    }
    case SymbolRef::ST_Data:
    case SymbolRef::ST_Function:
    case SymbolRef::ST_Other:
    case SymbolRef::ST_Unknown: {
      Value.SymbolName = TargetName.data();
      Value.Addend = Addend;

      // Absolute relocations will have a zero symbol ID (STN_UNDEF), which
      // will manifest here as a NULL symbol name.
      // We can set this as a valid (but empty) symbol name, and rely
      // on addRelocationForSymbol to handle this.
      if (!Value.SymbolName)
        Value.SymbolName = "";
      break;
    }
    default:
      llvm_unreachable("Unresolved symbol type!");
      break;
    }
  }

  uint64_t Offset = RelI->getOffset();

  LLVM_DEBUG(dbgs() << "\t\tSectionID: " << SectionID << " Offset: " << Offset
                    << "\n");
  if ((Arch == Triple::aarch64 || Arch == Triple::aarch64_be)) {
    if ((RelType == ELF::R_AARCH64_CALL26 ||
         RelType == ELF::R_AARCH64_JUMP26) &&
        MemMgr.allowStubAllocation()) {
      resolveAArch64Branch(SectionID, Value, RelI, Stubs);
    } else if (RelType == ELF::R_AARCH64_ADR_GOT_PAGE) {
      // Create new GOT entry or find existing one. If GOT entry is
      // to be created, then we also emit ABS64 relocation for it.
      uint64_t GOTOffset = findOrAllocGOTEntry(Value, ELF::R_AARCH64_ABS64);
      resolveGOTOffsetRelocation(SectionID, Offset, GOTOffset + Addend,
                                 ELF::R_AARCH64_ADR_PREL_PG_HI21);

    } else if (RelType == ELF::R_AARCH64_LD64_GOT_LO12_NC) {
      uint64_t GOTOffset = findOrAllocGOTEntry(Value, ELF::R_AARCH64_ABS64);
      resolveGOTOffsetRelocation(SectionID, Offset, GOTOffset + Addend,
                                 ELF::R_AARCH64_LDST64_ABS_LO12_NC);
    } else {
      processSimpleRelocation(SectionID, Offset, RelType, Value);
    }
  } else if (Arch == Triple::arm) {
    if (RelType == ELF::R_ARM_PC24 || RelType == ELF::R_ARM_CALL ||
      RelType == ELF::R_ARM_JUMP24) {
      // This is an ARM branch relocation, need to use a stub function.
      LLVM_DEBUG(dbgs() << "\t\tThis is an ARM branch relocation.\n");
      SectionEntry &Section = Sections[SectionID];

      // Look for an existing stub.
      StubMap::const_iterator i = Stubs.find(Value);
      if (i != Stubs.end()) {
        resolveRelocation(Section, Offset,
                          Section.getLoadAddressWithOffset(i->second), RelType,
                          0);
        LLVM_DEBUG(dbgs() << " Stub function found\n");
      } else {
        // Create a new stub function.
        LLVM_DEBUG(dbgs() << " Create a new stub function\n");
        Stubs[Value] = Section.getStubOffset();
        uint8_t *StubTargetAddr = createStubFunction(
            Section.getAddressWithOffset(Section.getStubOffset()));
        RelocationEntry RE(SectionID, StubTargetAddr - Section.getAddress(),
                           ELF::R_ARM_ABS32, Value.Addend);
        if (Value.SymbolName)
          addRelocationForSymbol(RE, Value.SymbolName);
        else
          addRelocationForSection(RE, Value.SectionID);

        resolveRelocation(
            Section, Offset,
            Section.getLoadAddressWithOffset(Section.getStubOffset()), RelType,
            0);
        Section.advanceStubOffset(getMaxStubSize());
      }
    } else {
      uint32_t *Placeholder =
        reinterpret_cast<uint32_t*>(computePlaceholderAddress(SectionID, Offset));
      if (RelType == ELF::R_ARM_PREL31 || RelType == ELF::R_ARM_TARGET1 ||
          RelType == ELF::R_ARM_ABS32) {
        Value.Addend += *Placeholder;
      } else if (RelType == ELF::R_ARM_MOVW_ABS_NC || RelType == ELF::R_ARM_MOVT_ABS) {
        // See ELF for ARM documentation
        Value.Addend += (int16_t)((*Placeholder & 0xFFF) | (((*Placeholder >> 16) & 0xF) << 12));
      }
      processSimpleRelocation(SectionID, Offset, RelType, Value);
    }
  } else if (Arch == Triple::loongarch64) {
    if (RelType == ELF::R_LARCH_B26 && MemMgr.allowStubAllocation()) {
      resolveLoongArch64Branch(SectionID, Value, RelI, Stubs);
    } else if (RelType == ELF::R_LARCH_GOT_PC_HI20 ||
               RelType == ELF::R_LARCH_GOT_PC_LO12) {
      uint64_t GOTOffset = findOrAllocGOTEntry(Value, ELF::R_LARCH_64);
      resolveGOTOffsetRelocation(SectionID, Offset, GOTOffset + Addend,
                                 RelType);
    } else {
      processSimpleRelocation(SectionID, Offset, RelType, Value);
    }
  } else if (IsMipsO32ABI) {
    uint8_t *Placeholder = reinterpret_cast<uint8_t *>(
        computePlaceholderAddress(SectionID, Offset));
    uint32_t Opcode = readBytesUnaligned(Placeholder, 4);
    if (RelType == ELF::R_MIPS_26) {
      // This is an Mips branch relocation, need to use a stub function.
      LLVM_DEBUG(dbgs() << "\t\tThis is a Mips branch relocation.");
      SectionEntry &Section = Sections[SectionID];

      // Extract the addend from the instruction.
      // We shift up by two since the Value will be down shifted again
      // when applying the relocation.
      uint32_t Addend = (Opcode & 0x03ffffff) << 2;

      Value.Addend += Addend;

      //  Look up for existing stub.
      StubMap::const_iterator i = Stubs.find(Value);
      if (i != Stubs.end()) {
        RelocationEntry RE(SectionID, Offset, RelType, i->second);
        addRelocationForSection(RE, SectionID);
        LLVM_DEBUG(dbgs() << " Stub function found\n");
      } else {
        // Create a new stub function.
        LLVM_DEBUG(dbgs() << " Create a new stub function\n");
        Stubs[Value] = Section.getStubOffset();

        unsigned AbiVariant = Obj.getPlatformFlags();

        uint8_t *StubTargetAddr = createStubFunction(
            Section.getAddressWithOffset(Section.getStubOffset()), AbiVariant);

        // Creating Hi and Lo relocations for the filled stub instructions.
        RelocationEntry REHi(SectionID, StubTargetAddr - Section.getAddress(),
                             ELF::R_MIPS_HI16, Value.Addend);
        RelocationEntry RELo(SectionID,
                             StubTargetAddr - Section.getAddress() + 4,
                             ELF::R_MIPS_LO16, Value.Addend);

        if (Value.SymbolName) {
          addRelocationForSymbol(REHi, Value.SymbolName);
          addRelocationForSymbol(RELo, Value.SymbolName);
        } else {
          addRelocationForSection(REHi, Value.SectionID);
          addRelocationForSection(RELo, Value.SectionID);
        }

        RelocationEntry RE(SectionID, Offset, RelType, Section.getStubOffset());
        addRelocationForSection(RE, SectionID);
        Section.advanceStubOffset(getMaxStubSize());
      }
    } else if (RelType == ELF::R_MIPS_HI16 || RelType == ELF::R_MIPS_PCHI16) {
      int64_t Addend = (Opcode & 0x0000ffff) << 16;
      RelocationEntry RE(SectionID, Offset, RelType, Addend);
      PendingRelocs.push_back(std::make_pair(Value, RE));
    } else if (RelType == ELF::R_MIPS_LO16 || RelType == ELF::R_MIPS_PCLO16) {
      int64_t Addend = Value.Addend + SignExtend32<16>(Opcode & 0x0000ffff);
      for (auto I = PendingRelocs.begin(); I != PendingRelocs.end();) {
        const RelocationValueRef &MatchingValue = I->first;
        RelocationEntry &Reloc = I->second;
        if (MatchingValue == Value &&
            RelType == getMatchingLoRelocation(Reloc.RelType) &&
            SectionID == Reloc.SectionID) {
          Reloc.Addend += Addend;
          if (Value.SymbolName)
            addRelocationForSymbol(Reloc, Value.SymbolName);
          else
            addRelocationForSection(Reloc, Value.SectionID);
          I = PendingRelocs.erase(I);
        } else
          ++I;
      }
      RelocationEntry RE(SectionID, Offset, RelType, Addend);
      if (Value.SymbolName)
        addRelocationForSymbol(RE, Value.SymbolName);
      else
        addRelocationForSection(RE, Value.SectionID);
    } else {
      if (RelType == ELF::R_MIPS_32)
        Value.Addend += Opcode;
      else if (RelType == ELF::R_MIPS_PC16)
        Value.Addend += SignExtend32<18>((Opcode & 0x0000ffff) << 2);
      else if (RelType == ELF::R_MIPS_PC19_S2)
        Value.Addend += SignExtend32<21>((Opcode & 0x0007ffff) << 2);
      else if (RelType == ELF::R_MIPS_PC21_S2)
        Value.Addend += SignExtend32<23>((Opcode & 0x001fffff) << 2);
      else if (RelType == ELF::R_MIPS_PC26_S2)
        Value.Addend += SignExtend32<28>((Opcode & 0x03ffffff) << 2);
      processSimpleRelocation(SectionID, Offset, RelType, Value);
    }
  } else if (IsMipsN32ABI || IsMipsN64ABI) {
    uint32_t r_type = RelType & 0xff;
    RelocationEntry RE(SectionID, Offset, RelType, Value.Addend);
    if (r_type == ELF::R_MIPS_CALL16 || r_type == ELF::R_MIPS_GOT_PAGE
        || r_type == ELF::R_MIPS_GOT_DISP) {
      auto [I, Inserted] = GOTSymbolOffsets.try_emplace(TargetName);
      if (Inserted)
        I->second = allocateGOTEntries(1);
      RE.SymOffset = I->second;
      if (Value.SymbolName)
        addRelocationForSymbol(RE, Value.SymbolName);
      else
        addRelocationForSection(RE, Value.SectionID);
    } else if (RelType == ELF::R_MIPS_26) {
      // This is an Mips branch relocation, need to use a stub function.
      LLVM_DEBUG(dbgs() << "\t\tThis is a Mips branch relocation.");
      SectionEntry &Section = Sections[SectionID];

      //  Look up for existing stub.
      StubMap::const_iterator i = Stubs.find(Value);
      if (i != Stubs.end()) {
        RelocationEntry RE(SectionID, Offset, RelType, i->second);
        addRelocationForSection(RE, SectionID);
        LLVM_DEBUG(dbgs() << " Stub function found\n");
      } else {
        // Create a new stub function.
        LLVM_DEBUG(dbgs() << " Create a new stub function\n");
        Stubs[Value] = Section.getStubOffset();

        unsigned AbiVariant = Obj.getPlatformFlags();

        uint8_t *StubTargetAddr = createStubFunction(
            Section.getAddressWithOffset(Section.getStubOffset()), AbiVariant);

        if (IsMipsN32ABI) {
          // Creating Hi and Lo relocations for the filled stub instructions.
          RelocationEntry REHi(SectionID, StubTargetAddr - Section.getAddress(),
                               ELF::R_MIPS_HI16, Value.Addend);
          RelocationEntry RELo(SectionID,
                               StubTargetAddr - Section.getAddress() + 4,
                               ELF::R_MIPS_LO16, Value.Addend);
          if (Value.SymbolName) {
            addRelocationForSymbol(REHi, Value.SymbolName);
            addRelocationForSymbol(RELo, Value.SymbolName);
          } else {
            addRelocationForSection(REHi, Value.SectionID);
            addRelocationForSection(RELo, Value.SectionID);
          }
        } else {
          // Creating Highest, Higher, Hi and Lo relocations for the filled stub
          // instructions.
          RelocationEntry REHighest(SectionID,
                                    StubTargetAddr - Section.getAddress(),
                                    ELF::R_MIPS_HIGHEST, Value.Addend);
          RelocationEntry REHigher(SectionID,
                                   StubTargetAddr - Section.getAddress() + 4,
                                   ELF::R_MIPS_HIGHER, Value.Addend);
          RelocationEntry REHi(SectionID,
                               StubTargetAddr - Section.getAddress() + 12,
                               ELF::R_MIPS_HI16, Value.Addend);
          RelocationEntry RELo(SectionID,
                               StubTargetAddr - Section.getAddress() + 20,
                               ELF::R_MIPS_LO16, Value.Addend);
          if (Value.SymbolName) {
            addRelocationForSymbol(REHighest, Value.SymbolName);
            addRelocationForSymbol(REHigher, Value.SymbolName);
            addRelocationForSymbol(REHi, Value.SymbolName);
            addRelocationForSymbol(RELo, Value.SymbolName);
          } else {
            addRelocationForSection(REHighest, Value.SectionID);
            addRelocationForSection(REHigher, Value.SectionID);
            addRelocationForSection(REHi, Value.SectionID);
            addRelocationForSection(RELo, Value.SectionID);
          }
        }
        RelocationEntry RE(SectionID, Offset, RelType, Section.getStubOffset());
        addRelocationForSection(RE, SectionID);
        Section.advanceStubOffset(getMaxStubSize());
      }
    } else {
      processSimpleRelocation(SectionID, Offset, RelType, Value);
    }

  } else if (Arch == Triple::ppc64 || Arch == Triple::ppc64le) {
    if (RelType == ELF::R_PPC64_REL24) {
      // Determine ABI variant in use for this object.
      unsigned AbiVariant = Obj.getPlatformFlags();
      AbiVariant &= ELF::EF_PPC64_ABI;
      // A PPC branch relocation will need a stub function if the target is
      // an external symbol (either Value.SymbolName is set, or SymType is
      // Symbol::ST_Unknown) or if the target address is not within the
      // signed 24-bits branch address.
      SectionEntry &Section = Sections[SectionID];
      uint8_t *Target = Section.getAddressWithOffset(Offset);
      bool RangeOverflow = false;
      bool IsExtern = Value.SymbolName || SymType == SymbolRef::ST_Unknown;
      if (!IsExtern) {
        if (AbiVariant != 2) {
          // In the ELFv1 ABI, a function call may point to the .opd entry,
          // so the final symbol value is calculated based on the relocation
          // values in the .opd section.
          if (auto Err = findOPDEntrySection(Obj, ObjSectionToID, Value))
            return std::move(Err);
        } else {
          // In the ELFv2 ABI, a function symbol may provide a local entry
          // point, which must be used for direct calls.
          if (Value.SectionID == SectionID){
            uint8_t SymOther = Symbol->getOther();
            Value.Addend += ELF::decodePPC64LocalEntryOffset(SymOther);
          }
        }
        uint8_t *RelocTarget =
            Sections[Value.SectionID].getAddressWithOffset(Value.Addend);
        int64_t delta = static_cast<int64_t>(Target - RelocTarget);
        // If it is within 26-bits branch range, just set the branch target
        if (SignExtend64<26>(delta) != delta) {
          RangeOverflow = true;
        } else if ((AbiVariant != 2) ||
                   (AbiVariant == 2  && Value.SectionID == SectionID)) {
          RelocationEntry RE(SectionID, Offset, RelType, Value.Addend);
          addRelocationForSection(RE, Value.SectionID);
        }
      }
      if (IsExtern || (AbiVariant == 2 && Value.SectionID != SectionID) ||
          RangeOverflow) {
        // It is an external symbol (either Value.SymbolName is set, or
        // SymType is SymbolRef::ST_Unknown) or out of range.
        StubMap::const_iterator i = Stubs.find(Value);
        if (i != Stubs.end()) {
          // Symbol function stub already created, just relocate to it
          resolveRelocation(Section, Offset,
                            Section.getLoadAddressWithOffset(i->second),
                            RelType, 0);
          LLVM_DEBUG(dbgs() << " Stub function found\n");
        } else {
          // Create a new stub function.
          LLVM_DEBUG(dbgs() << " Create a new stub function\n");
          Stubs[Value] = Section.getStubOffset();
          uint8_t *StubTargetAddr = createStubFunction(
              Section.getAddressWithOffset(Section.getStubOffset()),
              AbiVariant);
          RelocationEntry RE(SectionID, StubTargetAddr - Section.getAddress(),
                             ELF::R_PPC64_ADDR64, Value.Addend);

          // Generates the 64-bits address loads as exemplified in section
          // 4.5.1 in PPC64 ELF ABI.  Note that the relocations need to
          // apply to the low part of the instructions, so we have to update
          // the offset according to the target endianness.
          uint64_t StubRelocOffset = StubTargetAddr - Section.getAddress();
          if (!IsTargetLittleEndian)
            StubRelocOffset += 2;

          RelocationEntry REhst(SectionID, StubRelocOffset + 0,
                                ELF::R_PPC64_ADDR16_HIGHEST, Value.Addend);
          RelocationEntry REhr(SectionID, StubRelocOffset + 4,
                               ELF::R_PPC64_ADDR16_HIGHER, Value.Addend);
          RelocationEntry REh(SectionID, StubRelocOffset + 12,
                              ELF::R_PPC64_ADDR16_HI, Value.Addend);
          RelocationEntry REl(SectionID, StubRelocOffset + 16,
                              ELF::R_PPC64_ADDR16_LO, Value.Addend);

          if (Value.SymbolName) {
            addRelocationForSymbol(REhst, Value.SymbolName);
            addRelocationForSymbol(REhr, Value.SymbolName);
            addRelocationForSymbol(REh, Value.SymbolName);
            addRelocationForSymbol(REl, Value.SymbolName);
          } else {
            addRelocationForSection(REhst, Value.SectionID);
            addRelocationForSection(REhr, Value.SectionID);
            addRelocationForSection(REh, Value.SectionID);
            addRelocationForSection(REl, Value.SectionID);
          }

          resolveRelocation(
              Section, Offset,
              Section.getLoadAddressWithOffset(Section.getStubOffset()),
              RelType, 0);
          Section.advanceStubOffset(getMaxStubSize());
        }
        if (IsExtern || (AbiVariant == 2 && Value.SectionID != SectionID)) {
          // Restore the TOC for external calls
          if (AbiVariant == 2)
            writeInt32BE(Target + 4, 0xE8410018); // ld r2,24(r1)
          else
            writeInt32BE(Target + 4, 0xE8410028); // ld r2,40(r1)
        }
      }
    } else if (RelType == ELF::R_PPC64_TOC16 ||
               RelType == ELF::R_PPC64_TOC16_DS ||
               RelType == ELF::R_PPC64_TOC16_LO ||
               RelType == ELF::R_PPC64_TOC16_LO_DS ||
               RelType == ELF::R_PPC64_TOC16_HI ||
               RelType == ELF::R_PPC64_TOC16_HA) {
      // These relocations are supposed to subtract the TOC address from
      // the final value.  This does not fit cleanly into the RuntimeDyld
      // scheme, since there may be *two* sections involved in determining
      // the relocation value (the section of the symbol referred to by the
      // relocation, and the TOC section associated with the current module).
      //
      // Fortunately, these relocations are currently only ever generated
      // referring to symbols that themselves reside in the TOC, which means
      // that the two sections are actually the same.  Thus they cancel out
      // and we can immediately resolve the relocation right now.
      switch (RelType) {
      case ELF::R_PPC64_TOC16: RelType = ELF::R_PPC64_ADDR16; break;
      case ELF::R_PPC64_TOC16_DS: RelType = ELF::R_PPC64_ADDR16_DS; break;
      case ELF::R_PPC64_TOC16_LO: RelType = ELF::R_PPC64_ADDR16_LO; break;
      case ELF::R_PPC64_TOC16_LO_DS: RelType = ELF::R_PPC64_ADDR16_LO_DS; break;
      case ELF::R_PPC64_TOC16_HI: RelType = ELF::R_PPC64_ADDR16_HI; break;
      case ELF::R_PPC64_TOC16_HA: RelType = ELF::R_PPC64_ADDR16_HA; break;
      default: llvm_unreachable("Wrong relocation type.");
      }

      RelocationValueRef TOCValue;
      if (auto Err = findPPC64TOCSection(Obj, ObjSectionToID, TOCValue))
        return std::move(Err);
      if (Value.SymbolName || Value.SectionID != TOCValue.SectionID)
        llvm_unreachable("Unsupported TOC relocation.");
      Value.Addend -= TOCValue.Addend;
      resolveRelocation(Sections[SectionID], Offset, Value.Addend, RelType, 0);
    } else {
      // There are two ways to refer to the TOC address directly: either
      // via a ELF::R_PPC64_TOC relocation (where both symbol and addend are
      // ignored), or via any relocation that refers to the magic ".TOC."
      // symbols (in which case the addend is respected).
      if (RelType == ELF::R_PPC64_TOC) {
        RelType = ELF::R_PPC64_ADDR64;
        if (auto Err = findPPC64TOCSection(Obj, ObjSectionToID, Value))
          return std::move(Err);
      } else if (TargetName == ".TOC.") {
        if (auto Err = findPPC64TOCSection(Obj, ObjSectionToID, Value))
          return std::move(Err);
        Value.Addend += Addend;
      }

      RelocationEntry RE(SectionID, Offset, RelType, Value.Addend);

      if (Value.SymbolName)
        addRelocationForSymbol(RE, Value.SymbolName);
      else
        addRelocationForSection(RE, Value.SectionID);
    }
  } else if (Arch == Triple::systemz &&
             (RelType == ELF::R_390_PLT32DBL || RelType == ELF::R_390_GOTENT)) {
    // Create function stubs for both PLT and GOT references, regardless of
    // whether the GOT reference is to data or code.  The stub contains the
    // full address of the symbol, as needed by GOT references, and the
    // executable part only adds an overhead of 8 bytes.
    //
    // We could try to conserve space by allocating the code and data
    // parts of the stub separately.  However, as things stand, we allocate
    // a stub for every relocation, so using a GOT in JIT code should be
    // no less space efficient than using an explicit constant pool.
    LLVM_DEBUG(dbgs() << "\t\tThis is a SystemZ indirect relocation.");
    SectionEntry &Section = Sections[SectionID];

    // Look for an existing stub.
    StubMap::const_iterator i = Stubs.find(Value);
    uintptr_t StubAddress;
    if (i != Stubs.end()) {
      StubAddress = uintptr_t(Section.getAddressWithOffset(i->second));
      LLVM_DEBUG(dbgs() << " Stub function found\n");
    } else {
      // Create a new stub function.
      LLVM_DEBUG(dbgs() << " Create a new stub function\n");

      uintptr_t BaseAddress = uintptr_t(Section.getAddress());
      StubAddress =
          alignTo(BaseAddress + Section.getStubOffset(), getStubAlignment());
      unsigned StubOffset = StubAddress - BaseAddress;

      Stubs[Value] = StubOffset;
      createStubFunction((uint8_t *)StubAddress);
      RelocationEntry RE(SectionID, StubOffset + 8, ELF::R_390_64,
                         Value.Offset);
      if (Value.SymbolName)
        addRelocationForSymbol(RE, Value.SymbolName);
      else
        addRelocationForSection(RE, Value.SectionID);
      Section.advanceStubOffset(getMaxStubSize());
    }

    if (RelType == ELF::R_390_GOTENT)
      resolveRelocation(Section, Offset, StubAddress + 8, ELF::R_390_PC32DBL,
                        Addend);
    else
      resolveRelocation(Section, Offset, StubAddress, RelType, Addend);
  } else if (Arch == Triple::x86_64) {
    if (RelType == ELF::R_X86_64_PLT32) {
      // The way the PLT relocations normally work is that the linker allocates
      // the
      // PLT and this relocation makes a PC-relative call into the PLT.  The PLT
      // entry will then jump to an address provided by the GOT.  On first call,
      // the
      // GOT address will point back into PLT code that resolves the symbol. After
      // the first call, the GOT entry points to the actual function.
      //
      // For local functions we're ignoring all of that here and just replacing
      // the PLT32 relocation type with PC32, which will translate the relocation
      // into a PC-relative call directly to the function. For external symbols we
      // can't be sure the function will be within 2^32 bytes of the call site, so
      // we need to create a stub, which calls into the GOT.  This case is
      // equivalent to the usual PLT implementation except that we use the stub
      // mechanism in RuntimeDyld (which puts stubs at the end of the section)
      // rather than allocating a PLT section.
      if (Value.SymbolName && MemMgr.allowStubAllocation()) {
        // This is a call to an external function.
        // Look for an existing stub.
        SectionEntry *Section = &Sections[SectionID];
        StubMap::const_iterator i = Stubs.find(Value);
        uintptr_t StubAddress;
        if (i != Stubs.end()) {
          StubAddress = uintptr_t(Section->getAddress()) + i->second;
          LLVM_DEBUG(dbgs() << " Stub function found\n");
        } else {
          // Create a new stub function (equivalent to a PLT entry).
          LLVM_DEBUG(dbgs() << " Create a new stub function\n");

          uintptr_t BaseAddress = uintptr_t(Section->getAddress());
          StubAddress = alignTo(BaseAddress + Section->getStubOffset(),
                                getStubAlignment());
          unsigned StubOffset = StubAddress - BaseAddress;
          Stubs[Value] = StubOffset;
          createStubFunction((uint8_t *)StubAddress);

          // Bump our stub offset counter
          Section->advanceStubOffset(getMaxStubSize());

          // Allocate a GOT Entry
          uint64_t GOTOffset = allocateGOTEntries(1);
          // This potentially creates a new Section which potentially
          // invalidates the Section pointer, so reload it.
          Section = &Sections[SectionID];

          // The load of the GOT address has an addend of -4
          resolveGOTOffsetRelocation(SectionID, StubOffset + 2, GOTOffset - 4,
                                     ELF::R_X86_64_PC32);

          // Fill in the value of the symbol we're targeting into the GOT
          addRelocationForSymbol(
              computeGOTOffsetRE(GOTOffset, 0, ELF::R_X86_64_64),
              Value.SymbolName);
        }

        // Make the target call a call into the stub table.
        resolveRelocation(*Section, Offset, StubAddress, ELF::R_X86_64_PC32,
                          Addend);
      } else {
        Value.Addend += support::ulittle32_t::ref(
            computePlaceholderAddress(SectionID, Offset));
        processSimpleRelocation(SectionID, Offset, ELF::R_X86_64_PC32, Value);
      }
    } else if (RelType == ELF::R_X86_64_GOTPCREL ||
               RelType == ELF::R_X86_64_GOTPCRELX ||
               RelType == ELF::R_X86_64_REX_GOTPCRELX) {
      uint64_t GOTOffset = allocateGOTEntries(1);
      resolveGOTOffsetRelocation(SectionID, Offset, GOTOffset + Addend,
                                 ELF::R_X86_64_PC32);

      // Fill in the value of the symbol we're targeting into the GOT
      RelocationEntry RE =
          computeGOTOffsetRE(GOTOffset, Value.Offset, ELF::R_X86_64_64);
      if (Value.SymbolName)
        addRelocationForSymbol(RE, Value.SymbolName);
      else
        addRelocationForSection(RE, Value.SectionID);
    } else if (RelType == ELF::R_X86_64_GOT64) {
      // Fill in a 64-bit GOT offset.
      uint64_t GOTOffset = allocateGOTEntries(1);
      resolveRelocation(Sections[SectionID], Offset, GOTOffset,
                        ELF::R_X86_64_64, 0);

      // Fill in the value of the symbol we're targeting into the GOT
      RelocationEntry RE =
          computeGOTOffsetRE(GOTOffset, Value.Offset, ELF::R_X86_64_64);
      if (Value.SymbolName)
        addRelocationForSymbol(RE, Value.SymbolName);
      else
        addRelocationForSection(RE, Value.SectionID);
    } else if (RelType == ELF::R_X86_64_GOTPC32) {
      // Materialize the address of the base of the GOT relative to the PC.
      // This doesn't create a GOT entry, but it does mean we need a GOT
      // section.
      (void)allocateGOTEntries(0);
      resolveGOTOffsetRelocation(SectionID, Offset, Addend, ELF::R_X86_64_PC32);
    } else if (RelType == ELF::R_X86_64_GOTPC64) {
      (void)allocateGOTEntries(0);
      resolveGOTOffsetRelocation(SectionID, Offset, Addend, ELF::R_X86_64_PC64);
    } else if (RelType == ELF::R_X86_64_GOTOFF64) {
      // GOTOFF relocations ultimately require a section difference relocation.
      (void)allocateGOTEntries(0);
      processSimpleRelocation(SectionID, Offset, RelType, Value);
    } else if (RelType == ELF::R_X86_64_PC32) {
      Value.Addend += support::ulittle32_t::ref(computePlaceholderAddress(SectionID, Offset));
      processSimpleRelocation(SectionID, Offset, RelType, Value);
    } else if (RelType == ELF::R_X86_64_PC64) {
      Value.Addend += support::ulittle64_t::ref(
          computePlaceholderAddress(SectionID, Offset));
      processSimpleRelocation(SectionID, Offset, RelType, Value);
    } else if (RelType == ELF::R_X86_64_GOTTPOFF) {
      processX86_64GOTTPOFFRelocation(SectionID, Offset, Value, Addend);
    } else if (RelType == ELF::R_X86_64_TLSGD ||
               RelType == ELF::R_X86_64_TLSLD) {
      // The next relocation must be the relocation for __tls_get_addr.
      ++RelI;
      auto &GetAddrRelocation = *RelI;
      processX86_64TLSRelocation(SectionID, Offset, RelType, Value, Addend,
                                 GetAddrRelocation);
    } else {
      processSimpleRelocation(SectionID, Offset, RelType, Value);
    }
  } else if (Arch == Triple::riscv32 || Arch == Triple::riscv64) {
    // *_LO12 relocation receive information about a symbol from the
    // corresponding *_HI20 relocation, so we have to collect this information
    // before resolving
    if (RelType == ELF::R_RISCV_GOT_HI20 ||
        RelType == ELF::R_RISCV_PCREL_HI20 ||
        RelType == ELF::R_RISCV_TPREL_HI20 ||
        RelType == ELF::R_RISCV_TLS_GD_HI20 ||
        RelType == ELF::R_RISCV_TLS_GOT_HI20) {
      RelocationEntry RE(SectionID, Offset, RelType, Addend);
      PendingRelocs.push_back({Value, RE});
    }
    processSimpleRelocation(SectionID, Offset, RelType, Value);
  } else {
    if (Arch == Triple::x86) {
      Value.Addend += support::ulittle32_t::ref(
          computePlaceholderAddress(SectionID, Offset));
    }
    processSimpleRelocation(SectionID, Offset, RelType, Value);
  }
  return ++RelI;
}

void RuntimeDyldELF::processX86_64GOTTPOFFRelocation(unsigned SectionID,
                                                     uint64_t Offset,
                                                     RelocationValueRef Value,
                                                     int64_t Addend) {
  // Use the approach from "x86-64 Linker Optimizations" from the TLS spec
  // to replace the GOTTPOFF relocation with a TPOFF relocation. The spec
  // only mentions one optimization even though there are two different
  // code sequences for the Initial Exec TLS Model. We match the code to
  // find out which one was used.

  // A possible TLS code sequence and its replacement
  struct CodeSequence {
    // The expected code sequence
    ArrayRef<uint8_t> ExpectedCodeSequence;
    // The negative offset of the GOTTPOFF relocation to the beginning of
    // the sequence
    uint64_t TLSSequenceOffset;
    // The new code sequence
    ArrayRef<uint8_t> NewCodeSequence;
    // The offset of the new TPOFF relocation
    uint64_t TpoffRelocationOffset;
  };

  std::array<CodeSequence, 2> CodeSequences;

  // Initial Exec Code Model Sequence
  {
    static const std::initializer_list<uint8_t> ExpectedCodeSequenceList = {
        0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00,
        0x00,                                    // mov %fs:0, %rax
        0x48, 0x03, 0x05, 0x00, 0x00, 0x00, 0x00 // add x@gotpoff(%rip),
                                                 // %rax
    };
    CodeSequences[0].ExpectedCodeSequence =
        ArrayRef<uint8_t>(ExpectedCodeSequenceList);
    CodeSequences[0].TLSSequenceOffset = 12;

    static const std::initializer_list<uint8_t> NewCodeSequenceList = {
        0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00, // mov %fs:0, %rax
        0x48, 0x8d, 0x80, 0x00, 0x00, 0x00, 0x00 // lea x@tpoff(%rax), %rax
    };
    CodeSequences[0].NewCodeSequence = ArrayRef<uint8_t>(NewCodeSequenceList);
    CodeSequences[0].TpoffRelocationOffset = 12;
  }

  // Initial Exec Code Model Sequence, II
  {
    static const std::initializer_list<uint8_t> ExpectedCodeSequenceList = {
        0x48, 0x8b, 0x05, 0x00, 0x00, 0x00, 0x00, // mov x@gotpoff(%rip), %rax
        0x64, 0x48, 0x8b, 0x00, 0x00, 0x00, 0x00  // mov %fs:(%rax), %rax
    };
    CodeSequences[1].ExpectedCodeSequence =
        ArrayRef<uint8_t>(ExpectedCodeSequenceList);
    CodeSequences[1].TLSSequenceOffset = 3;

    static const std::initializer_list<uint8_t> NewCodeSequenceList = {
        0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00,             // 6 byte nop
        0x64, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00, // mov %fs:x@tpoff, %rax
    };
    CodeSequences[1].NewCodeSequence = ArrayRef<uint8_t>(NewCodeSequenceList);
    CodeSequences[1].TpoffRelocationOffset = 10;
  }

  bool Resolved = false;
  auto &Section = Sections[SectionID];
  for (const auto &C : CodeSequences) {
    assert(C.ExpectedCodeSequence.size() == C.NewCodeSequence.size() &&
           "Old and new code sequences must have the same size");

    if (Offset < C.TLSSequenceOffset ||
        (Offset - C.TLSSequenceOffset + C.NewCodeSequence.size()) >
            Section.getSize()) {
      // This can't be a matching sequence as it doesn't fit in the current
      // section
      continue;
    }

    auto TLSSequenceStartOffset = Offset - C.TLSSequenceOffset;
    auto *TLSSequence = Section.getAddressWithOffset(TLSSequenceStartOffset);
    if (ArrayRef<uint8_t>(TLSSequence, C.ExpectedCodeSequence.size()) !=
        C.ExpectedCodeSequence) {
      continue;
    }

    memcpy(TLSSequence, C.NewCodeSequence.data(), C.NewCodeSequence.size());

    // The original GOTTPOFF relocation has an addend as it is PC relative,
    // so it needs to be corrected. The TPOFF32 relocation is used as an
    // absolute value (which is an offset from %fs:0), so remove the addend
    // again.
    RelocationEntry RE(SectionID,
                       TLSSequenceStartOffset + C.TpoffRelocationOffset,
                       ELF::R_X86_64_TPOFF32, Value.Addend - Addend);

    if (Value.SymbolName)
      addRelocationForSymbol(RE, Value.SymbolName);
    else
      addRelocationForSection(RE, Value.SectionID);

    Resolved = true;
    break;
  }

  if (!Resolved) {
    // The GOTTPOFF relocation was not used in one of the sequences
    // described in the spec, so we can't optimize it to a TPOFF
    // relocation.
    uint64_t GOTOffset = allocateGOTEntries(1);
    resolveGOTOffsetRelocation(SectionID, Offset, GOTOffset + Addend,
                               ELF::R_X86_64_PC32);
    RelocationEntry RE =
        computeGOTOffsetRE(GOTOffset, Value.Offset, ELF::R_X86_64_TPOFF64);
    if (Value.SymbolName)
      addRelocationForSymbol(RE, Value.SymbolName);
    else
      addRelocationForSection(RE, Value.SectionID);
  }
}

void RuntimeDyldELF::processX86_64TLSRelocation(
    unsigned SectionID, uint64_t Offset, uint64_t RelType,
    RelocationValueRef Value, int64_t Addend,
    const RelocationRef &GetAddrRelocation) {
  // Since we are statically linking and have no additional DSOs, we can resolve
  // the relocation directly without using __tls_get_addr.
  // Use the approach from "x86-64 Linker Optimizations" from the TLS spec
  // to replace it with the Local Exec relocation variant.

  // Find out whether the code was compiled with the large or small memory
  // model. For this we look at the next relocation which is the relocation
  // for the __tls_get_addr function. If it's a 32 bit relocation, it's the
  // small code model, with a 64 bit relocation it's the large code model.
  bool IsSmallCodeModel;
  // Is the relocation for the __tls_get_addr a PC-relative GOT relocation?
  bool IsGOTPCRel = false;

  switch (GetAddrRelocation.getType()) {
  case ELF::R_X86_64_GOTPCREL:
  case ELF::R_X86_64_REX_GOTPCRELX:
  case ELF::R_X86_64_GOTPCRELX:
    IsGOTPCRel = true;
    [[fallthrough]];
  case ELF::R_X86_64_PLT32:
    IsSmallCodeModel = true;
    break;
  case ELF::R_X86_64_PLTOFF64:
    IsSmallCodeModel = false;
    break;
  default:
    report_fatal_error(
        "invalid TLS relocations for General/Local Dynamic TLS Model: "
        "expected PLT or GOT relocation for __tls_get_addr function");
  }

  // The negative offset to the start of the TLS code sequence relative to
  // the offset of the TLSGD/TLSLD relocation
  uint64_t TLSSequenceOffset;
  // The expected start of the code sequence
  ArrayRef<uint8_t> ExpectedCodeSequence;
  // The new TLS code sequence that will replace the existing code
  ArrayRef<uint8_t> NewCodeSequence;

  if (RelType == ELF::R_X86_64_TLSGD) {
    // The offset of the new TPOFF32 relocation (offset starting from the
    // beginning of the whole TLS sequence)
    uint64_t TpoffRelocOffset;

    if (IsSmallCodeModel) {
      if (!IsGOTPCRel) {
        static const std::initializer_list<uint8_t> CodeSequence = {
            0x66, // data16 (no-op prefix)
            0x48, 0x8d, 0x3d, 0x00, 0x00,
            0x00, 0x00,                  // lea <disp32>(%rip), %rdi
            0x66, 0x66,                  // two data16 prefixes
            0x48,                        // rex64 (no-op prefix)
            0xe8, 0x00, 0x00, 0x00, 0x00 // call __tls_get_addr@plt
        };
        ExpectedCodeSequence = ArrayRef<uint8_t>(CodeSequence);
        TLSSequenceOffset = 4;
      } else {
        // This code sequence is not described in the TLS spec but gcc
        // generates it sometimes.
        static const std::initializer_list<uint8_t> CodeSequence = {
            0x66, // data16 (no-op prefix)
            0x48, 0x8d, 0x3d, 0x00, 0x00,
            0x00, 0x00, // lea <disp32>(%rip), %rdi
            0x66,       // data16 prefix (no-op prefix)
            0x48,       // rex64 (no-op prefix)
            0xff, 0x15, 0x00, 0x00, 0x00,
            0x00 // call *__tls_get_addr@gotpcrel(%rip)
        };
        ExpectedCodeSequence = ArrayRef<uint8_t>(CodeSequence);
        TLSSequenceOffset = 4;
      }

      // The replacement code for the small code model. It's the same for
      // both sequences.
      static const std::initializer_list<uint8_t> SmallSequence = {
          0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00,
          0x00,                                    // mov %fs:0, %rax
          0x48, 0x8d, 0x80, 0x00, 0x00, 0x00, 0x00 // lea x@tpoff(%rax),
                                                   // %rax
      };
      NewCodeSequence = ArrayRef<uint8_t>(SmallSequence);
      TpoffRelocOffset = 12;
    } else {
      static const std::initializer_list<uint8_t> CodeSequence = {
          0x48, 0x8d, 0x3d, 0x00, 0x00, 0x00, 0x00, // lea <disp32>(%rip),
                                                    // %rdi
          0x48, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
          0x00,             // movabs $__tls_get_addr@pltoff, %rax
          0x48, 0x01, 0xd8, // add %rbx, %rax
          0xff, 0xd0        // call *%rax
      };
      ExpectedCodeSequence = ArrayRef<uint8_t>(CodeSequence);
      TLSSequenceOffset = 3;

      // The replacement code for the large code model
      static const std::initializer_list<uint8_t> LargeSequence = {
          0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00,
          0x00,                                     // mov %fs:0, %rax
          0x48, 0x8d, 0x80, 0x00, 0x00, 0x00, 0x00, // lea x@tpoff(%rax),
                                                    // %rax
          0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00        // nopw 0x0(%rax,%rax,1)
      };
      NewCodeSequence = ArrayRef<uint8_t>(LargeSequence);
      TpoffRelocOffset = 12;
    }

    // The TLSGD/TLSLD relocations are PC-relative, so they have an addend.
    // The new TPOFF32 relocations is used as an absolute offset from
    // %fs:0, so remove the TLSGD/TLSLD addend again.
    RelocationEntry RE(SectionID, Offset - TLSSequenceOffset + TpoffRelocOffset,
                       ELF::R_X86_64_TPOFF32, Value.Addend - Addend);
    if (Value.SymbolName)
      addRelocationForSymbol(RE, Value.SymbolName);
    else
      addRelocationForSection(RE, Value.SectionID);
  } else if (RelType == ELF::R_X86_64_TLSLD) {
    if (IsSmallCodeModel) {
      if (!IsGOTPCRel) {
        static const std::initializer_list<uint8_t> CodeSequence = {
            0x48, 0x8d, 0x3d, 0x00, 0x00, 0x00, // leaq <disp32>(%rip), %rdi
            0x00, 0xe8, 0x00, 0x00, 0x00, 0x00  // call __tls_get_addr@plt
        };
        ExpectedCodeSequence = ArrayRef<uint8_t>(CodeSequence);
        TLSSequenceOffset = 3;

        // The replacement code for the small code model
        static const std::initializer_list<uint8_t> SmallSequence = {
            0x66, 0x66, 0x66, // three data16 prefixes (no-op)
            0x64, 0x48, 0x8b, 0x04, 0x25,
            0x00, 0x00, 0x00, 0x00 // mov %fs:0, %rax
        };
        NewCodeSequence = ArrayRef<uint8_t>(SmallSequence);
      } else {
        // This code sequence is not described in the TLS spec but gcc
        // generates it sometimes.
        static const std::initializer_list<uint8_t> CodeSequence = {
            0x48, 0x8d, 0x3d, 0x00,
            0x00, 0x00, 0x00, // leaq <disp32>(%rip), %rdi
            0xff, 0x15, 0x00, 0x00,
            0x00, 0x00 // call
                       // *__tls_get_addr@gotpcrel(%rip)
        };
        ExpectedCodeSequence = ArrayRef<uint8_t>(CodeSequence);
        TLSSequenceOffset = 3;

        // The replacement is code is just like above but it needs to be
        // one byte longer.
        static const std::initializer_list<uint8_t> SmallSequence = {
            0x0f, 0x1f, 0x40, 0x00, // 4 byte nop
            0x64, 0x48, 0x8b, 0x04, 0x25,
            0x00, 0x00, 0x00, 0x00 // mov %fs:0, %rax
        };
        NewCodeSequence = ArrayRef<uint8_t>(SmallSequence);
      }
    } else {
      // This is the same sequence as for the TLSGD sequence with the large
      // memory model above
      static const std::initializer_list<uint8_t> CodeSequence = {
          0x48, 0x8d, 0x3d, 0x00, 0x00, 0x00, 0x00, // lea <disp32>(%rip),
                                                    // %rdi
          0x48, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
          0x48,       // movabs $__tls_get_addr@pltoff, %rax
          0x01, 0xd8, // add %rbx, %rax
          0xff, 0xd0  // call *%rax
      };
      ExpectedCodeSequence = ArrayRef<uint8_t>(CodeSequence);
      TLSSequenceOffset = 3;

      // The replacement code for the large code model
      static const std::initializer_list<uint8_t> LargeSequence = {
          0x66, 0x66, 0x66, // three data16 prefixes (no-op)
          0x66, 0x66, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00,
          0x00,                                                // 10 byte nop
          0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00 // mov %fs:0,%rax
      };
      NewCodeSequence = ArrayRef<uint8_t>(LargeSequence);
    }
  } else {
    llvm_unreachable("both TLS relocations handled above");
  }

  assert(ExpectedCodeSequence.size() == NewCodeSequence.size() &&
         "Old and new code sequences must have the same size");

  auto &Section = Sections[SectionID];
  if (Offset < TLSSequenceOffset ||
      (Offset - TLSSequenceOffset + NewCodeSequence.size()) >
          Section.getSize()) {
    report_fatal_error("unexpected end of section in TLS sequence");
  }

  auto *TLSSequence = Section.getAddressWithOffset(Offset - TLSSequenceOffset);
  if (ArrayRef<uint8_t>(TLSSequence, ExpectedCodeSequence.size()) !=
      ExpectedCodeSequence) {
    report_fatal_error(
        "invalid TLS sequence for Global/Local Dynamic TLS Model");
  }

  memcpy(TLSSequence, NewCodeSequence.data(), NewCodeSequence.size());
}

size_t RuntimeDyldELF::getGOTEntrySize() {
  // We don't use the GOT in all of these cases, but it's essentially free
  // to put them all here.
  size_t Result = 0;
  switch (Arch) {
  case Triple::x86_64:
  case Triple::aarch64:
  case Triple::aarch64_be:
  case Triple::loongarch64:
  case Triple::ppc64:
  case Triple::ppc64le:
  case Triple::systemz:
    Result = sizeof(uint64_t);
    break;
  case Triple::x86:
  case Triple::arm:
  case Triple::thumb:
    Result = sizeof(uint32_t);
    break;
  case Triple::mips:
  case Triple::mipsel:
  case Triple::mips64:
  case Triple::mips64el:
    if (IsMipsO32ABI || IsMipsN32ABI)
      Result = sizeof(uint32_t);
    else if (IsMipsN64ABI)
      Result = sizeof(uint64_t);
    else
      llvm_unreachable("Mips ABI not handled");
    break;
  default:
    llvm_unreachable("Unsupported CPU type!");
  }
  return Result;
}

uint64_t RuntimeDyldELF::allocateGOTEntries(unsigned no) {
  if (GOTSectionID == 0) {
    GOTSectionID = Sections.size();
    // Reserve a section id. We'll allocate the section later
    // once we know the total size
    Sections.push_back(SectionEntry(".got", nullptr, 0, 0, 0));
  }
  uint64_t StartOffset = CurrentGOTIndex * getGOTEntrySize();
  CurrentGOTIndex += no;
  return StartOffset;
}

uint64_t RuntimeDyldELF::findOrAllocGOTEntry(const RelocationValueRef &Value,
                                             unsigned GOTRelType) {
  auto E = GOTOffsetMap.insert({Value, 0});
  if (E.second) {
    uint64_t GOTOffset = allocateGOTEntries(1);

    // Create relocation for newly created GOT entry
    RelocationEntry RE =
        computeGOTOffsetRE(GOTOffset, Value.Offset, GOTRelType);
    if (Value.SymbolName)
      addRelocationForSymbol(RE, Value.SymbolName);
    else
      addRelocationForSection(RE, Value.SectionID);

    E.first->second = GOTOffset;
  }

  return E.first->second;
}

void RuntimeDyldELF::resolveGOTOffsetRelocation(unsigned SectionID,
                                                uint64_t Offset,
                                                uint64_t GOTOffset,
                                                uint32_t Type) {
  // Fill in the relative address of the GOT Entry into the stub
  RelocationEntry GOTRE(SectionID, Offset, Type, GOTOffset);
  addRelocationForSection(GOTRE, GOTSectionID);
}

RelocationEntry RuntimeDyldELF::computeGOTOffsetRE(uint64_t GOTOffset,
                                                   uint64_t SymbolOffset,
                                                   uint32_t Type) {
  return RelocationEntry(GOTSectionID, GOTOffset, Type, SymbolOffset);
}

void RuntimeDyldELF::processNewSymbol(const SymbolRef &ObjSymbol, SymbolTableEntry& Symbol) {
  // This should never return an error as `processNewSymbol` wouldn't have been
  // called if getFlags() returned an error before.
  auto ObjSymbolFlags = cantFail(ObjSymbol.getFlags());

  if (ObjSymbolFlags & SymbolRef::SF_Indirect) {
    if (IFuncStubSectionID == 0) {
      // Create a dummy section for the ifunc stubs. It will be actually
      // allocated in finalizeLoad() below.
      IFuncStubSectionID = Sections.size();
      Sections.push_back(
          SectionEntry(".text.__llvm_IFuncStubs", nullptr, 0, 0, 0));
      // First 64B are reserverd for the IFunc resolver
      IFuncStubOffset = 64;
    }

    IFuncStubs.push_back(IFuncStub{IFuncStubOffset, Symbol});
    // Modify the symbol so that it points to the ifunc stub instead of to the
    // resolver function.
    Symbol = SymbolTableEntry(IFuncStubSectionID, IFuncStubOffset,
                              Symbol.getFlags());
    IFuncStubOffset += getMaxIFuncStubSize();
  }
}

Error RuntimeDyldELF::finalizeLoad(const ObjectFile &Obj,
                                  ObjSectionToIDMap &SectionMap) {
  if (IsMipsO32ABI)
    if (!PendingRelocs.empty())
      return make_error<RuntimeDyldError>("Can't find matching LO16 reloc");

  // Create the IFunc stubs if necessary. This must be done before processing
  // the GOT entries, as the IFunc stubs may create some.
  if (IFuncStubSectionID != 0) {
    uint8_t *IFuncStubsAddr = MemMgr.allocateCodeSection(
        IFuncStubOffset, 1, IFuncStubSectionID, ".text.__llvm_IFuncStubs");
    if (!IFuncStubsAddr)
      return make_error<RuntimeDyldError>(
          "Unable to allocate memory for IFunc stubs!");
    Sections[IFuncStubSectionID] =
        SectionEntry(".text.__llvm_IFuncStubs", IFuncStubsAddr, IFuncStubOffset,
                     IFuncStubOffset, 0);

    createIFuncResolver(IFuncStubsAddr);

    LLVM_DEBUG(dbgs() << "Creating IFunc stubs SectionID: "
                      << IFuncStubSectionID << " Addr: "
                      << Sections[IFuncStubSectionID].getAddress() << '\n');
    for (auto &IFuncStub : IFuncStubs) {
      auto &Symbol = IFuncStub.OriginalSymbol;
      LLVM_DEBUG(dbgs() << "\tSectionID: " << Symbol.getSectionID()
                        << " Offset: " << format("%p", Symbol.getOffset())
                        << " IFuncStubOffset: "
                        << format("%p\n", IFuncStub.StubOffset));
      createIFuncStub(IFuncStubSectionID, 0, IFuncStub.StubOffset,
                      Symbol.getSectionID(), Symbol.getOffset());
    }

    IFuncStubSectionID = 0;
    IFuncStubOffset = 0;
    IFuncStubs.clear();
  }

  // If necessary, allocate the global offset table
  if (GOTSectionID != 0) {
    // Allocate memory for the section
    size_t TotalSize = CurrentGOTIndex * getGOTEntrySize();
    uint8_t *Addr = MemMgr.allocateDataSection(TotalSize, getGOTEntrySize(),
                                               GOTSectionID, ".got", false);
    if (!Addr)
      return make_error<RuntimeDyldError>("Unable to allocate memory for GOT!");

    Sections[GOTSectionID] =
        SectionEntry(".got", Addr, TotalSize, TotalSize, 0);

    // For now, initialize all GOT entries to zero.  We'll fill them in as
    // needed when GOT-based relocations are applied.
    memset(Addr, 0, TotalSize);
    if (IsMipsN32ABI || IsMipsN64ABI) {
      // To correctly resolve Mips GOT relocations, we need a mapping from
      // object's sections to GOTs.
      for (section_iterator SI = Obj.section_begin(), SE = Obj.section_end();
           SI != SE; ++SI) {
        if (SI->relocation_begin() != SI->relocation_end()) {
          Expected<section_iterator> RelSecOrErr = SI->getRelocatedSection();
          if (!RelSecOrErr)
            return make_error<RuntimeDyldError>(
                toString(RelSecOrErr.takeError()));

          section_iterator RelocatedSection = *RelSecOrErr;
          ObjSectionToIDMap::iterator i = SectionMap.find(*RelocatedSection);
          assert(i != SectionMap.end());
          SectionToGOTMap[i->second] = GOTSectionID;
        }
      }
      GOTSymbolOffsets.clear();
    }
  }

  // Look for and record the EH frame section.
  ObjSectionToIDMap::iterator i, e;
  for (i = SectionMap.begin(), e = SectionMap.end(); i != e; ++i) {
    const SectionRef &Section = i->first;

    StringRef Name;
    Expected<StringRef> NameOrErr = Section.getName();
    if (NameOrErr)
      Name = *NameOrErr;
    else
      consumeError(NameOrErr.takeError());

    if (Name == ".eh_frame") {
      UnregisteredEHFrameSections.push_back(i->second);
      break;
    }
  }

  GOTOffsetMap.clear();
  GOTSectionID = 0;
  CurrentGOTIndex = 0;

  return Error::success();
}

bool RuntimeDyldELF::isCompatibleFile(const object::ObjectFile &Obj) const {
  return Obj.isELF();
}

void RuntimeDyldELF::createIFuncResolver(uint8_t *Addr) const {
  if (Arch == Triple::x86_64) {
    // The adddres of the GOT1 entry is in %r11, the GOT2 entry is in %r11+8
    // (see createIFuncStub() for details)
    // The following code first saves all registers that contain the original
    // function arguments as those registers are not saved by the resolver
    // function. %r11 is saved as well so that the GOT2 entry can be updated
    // afterwards. Then it calls the actual IFunc resolver function whose
    // address is stored in GOT2. After the resolver function returns, all
    // saved registers are restored and the return value is written to GOT1.
    // Finally, jump to the now resolved function.
    // clang-format off
    const uint8_t StubCode[] = {
        0x57,                   // push %rdi
        0x56,                   // push %rsi
        0x52,                   // push %rdx
        0x51,                   // push %rcx
        0x41, 0x50,             // push %r8
        0x41, 0x51,             // push %r9
        0x41, 0x53,             // push %r11
        0x41, 0xff, 0x53, 0x08, // call *0x8(%r11)
        0x41, 0x5b,             // pop %r11
        0x41, 0x59,             // pop %r9
        0x41, 0x58,             // pop %r8
        0x59,                   // pop %rcx
        0x5a,                   // pop %rdx
        0x5e,                   // pop %rsi
        0x5f,                   // pop %rdi
        0x49, 0x89, 0x03,       // mov %rax,(%r11)
        0xff, 0xe0              // jmp *%rax
    };
    // clang-format on
    static_assert(sizeof(StubCode) <= 64,
                  "maximum size of the IFunc resolver is 64B");
    memcpy(Addr, StubCode, sizeof(StubCode));
  } else {
    report_fatal_error(
        "IFunc resolver is not supported for target architecture");
  }
}

void RuntimeDyldELF::createIFuncStub(unsigned IFuncStubSectionID,
                                     uint64_t IFuncResolverOffset,
                                     uint64_t IFuncStubOffset,
                                     unsigned IFuncSectionID,
                                     uint64_t IFuncOffset) {
  auto &IFuncStubSection = Sections[IFuncStubSectionID];
  auto *Addr = IFuncStubSection.getAddressWithOffset(IFuncStubOffset);

  if (Arch == Triple::x86_64) {
    // The first instruction loads a PC-relative address into %r11 which is a
    // GOT entry for this stub. This initially contains the address to the
    // IFunc resolver. We can use %r11 here as it's caller saved but not used
    // to pass any arguments. In fact, x86_64 ABI even suggests using %r11 for
    // code in the PLT. The IFunc resolver will use %r11 to update the GOT
    // entry.
    //
    // The next instruction just jumps to the address contained in the GOT
    // entry. As mentioned above, we do this two-step jump by first setting
    // %r11 so that the IFunc resolver has access to it.
    //
    // The IFunc resolver of course also needs to know the actual address of
    // the actual IFunc resolver function. This will be stored in a GOT entry
    // right next to the first one for this stub. So, the IFunc resolver will
    // be able to call it with %r11+8.
    //
    // In total, two adjacent GOT entries (+relocation) and one additional
    // relocation are required:
    // GOT1: Address of the IFunc resolver.
    // GOT2: Address of the IFunc resolver function.
    // IFuncStubOffset+3: 32-bit PC-relative address of GOT1.
    uint64_t GOT1 = allocateGOTEntries(2);
    uint64_t GOT2 = GOT1 + getGOTEntrySize();

    RelocationEntry RE1(GOTSectionID, GOT1, ELF::R_X86_64_64,
                        IFuncResolverOffset, {});
    addRelocationForSection(RE1, IFuncStubSectionID);
    RelocationEntry RE2(GOTSectionID, GOT2, ELF::R_X86_64_64, IFuncOffset, {});
    addRelocationForSection(RE2, IFuncSectionID);

    const uint8_t StubCode[] = {
        0x4c, 0x8d, 0x1d, 0x00, 0x00, 0x00, 0x00, // leaq 0x0(%rip),%r11
        0x41, 0xff, 0x23                          // jmpq *(%r11)
    };
    assert(sizeof(StubCode) <= getMaxIFuncStubSize() &&
           "IFunc stub size must not exceed getMaxIFuncStubSize()");
    memcpy(Addr, StubCode, sizeof(StubCode));

    // The PC-relative value starts 4 bytes from the end of the leaq
    // instruction, so the addend is -4.
    resolveGOTOffsetRelocation(IFuncStubSectionID, IFuncStubOffset + 3,
                               GOT1 - 4, ELF::R_X86_64_PC32);
  } else {
    report_fatal_error("IFunc stub is not supported for target architecture");
  }
}

unsigned RuntimeDyldELF::getMaxIFuncStubSize() const {
  if (Arch == Triple::x86_64) {
    return 10;
  }
  return 0;
}

bool RuntimeDyldELF::relocationNeedsGot(const RelocationRef &R) const {
  unsigned RelTy = R.getType();
  if (Arch == Triple::aarch64 || Arch == Triple::aarch64_be)
    return RelTy == ELF::R_AARCH64_ADR_GOT_PAGE ||
           RelTy == ELF::R_AARCH64_LD64_GOT_LO12_NC;

  if (Arch == Triple::loongarch64)
    return RelTy == ELF::R_LARCH_GOT_PC_HI20 ||
           RelTy == ELF::R_LARCH_GOT_PC_LO12;

  if (Arch == Triple::x86_64)
    return RelTy == ELF::R_X86_64_GOTPCREL ||
           RelTy == ELF::R_X86_64_GOTPCRELX ||
           RelTy == ELF::R_X86_64_GOT64 ||
           RelTy == ELF::R_X86_64_REX_GOTPCRELX;
  return false;
}

bool RuntimeDyldELF::relocationNeedsStub(const RelocationRef &R) const {
  if (Arch != Triple::x86_64)
    return true;  // Conservative answer

  switch (R.getType()) {
  default:
    return true;  // Conservative answer


  case ELF::R_X86_64_GOTPCREL:
  case ELF::R_X86_64_GOTPCRELX:
  case ELF::R_X86_64_REX_GOTPCRELX:
  case ELF::R_X86_64_GOTPC64:
  case ELF::R_X86_64_GOT64:
  case ELF::R_X86_64_GOTOFF64:
  case ELF::R_X86_64_PC32:
  case ELF::R_X86_64_PC64:
  case ELF::R_X86_64_64:
    // We know that these reloation types won't need a stub function.  This list
    // can be extended as needed.
    return false;
  }
}

} // namespace llvm
