//===- SyntheticSections.cpp ----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file contains linker-synthesized sections. Currently,
// synthetic sections are created either output sections or input sections,
// but we are rewriting code so that all synthetic sections are created as
// input sections.
//
//===----------------------------------------------------------------------===//

#include "SyntheticSections.h"
#include "Config.h"
#include "InputFiles.h"
#include "LinkerScript.h"
#include "OutputSections.h"
#include "SymbolTable.h"
#include "Symbols.h"
#include "Target.h"
#include "Writer.h"
#include "lld/Common/ErrorHandler.h"
#include "lld/Common/Memory.h"
#include "lld/Common/Strings.h"
#include "lld/Common/Threads.h"
#include "lld/Common/Version.h"
#include "llvm/ADT/SetOperations.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugPubTable.h"
#include "llvm/Object/ELFObjectFile.h"
#include "llvm/Support/Compression.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/LEB128.h"
#include "llvm/Support/MD5.h"
#include "llvm/Support/RandomNumberGenerator.h"
#include "llvm/Support/SHA1.h"
#include "llvm/Support/xxhash.h"
#include <cstdlib>
#include <thread>

using namespace llvm;
using namespace llvm::dwarf;
using namespace llvm::ELF;
using namespace llvm::object;
using namespace llvm::support;

using namespace lld;
using namespace lld::elf;

using llvm::support::endian::read32le;
using llvm::support::endian::write32le;
using llvm::support::endian::write64le;

constexpr size_t MergeNoTailSection::NumShards;

static uint64_t readUint(uint8_t *Buf) {
  return Config->Is64 ? read64(Buf) : read32(Buf);
}

static void writeUint(uint8_t *Buf, uint64_t Val) {
  if (Config->Is64)
    write64(Buf, Val);
  else
    write32(Buf, Val);
}

// Returns an LLD version string.
static ArrayRef<uint8_t> getVersion() {
  // Check LLD_VERSION first for ease of testing.
  // You can get consistent output by using the environment variable.
  // This is only for testing.
  StringRef S = getenv("LLD_VERSION");
  if (S.empty())
    S = Saver.save(Twine("Linker: ") + getLLDVersion());

  // +1 to include the terminating '\0'.
  return {(const uint8_t *)S.data(), S.size() + 1};
}

// Creates a .comment section containing LLD version info.
// With this feature, you can identify LLD-generated binaries easily
// by "readelf --string-dump .comment <file>".
// The returned object is a mergeable string section.
MergeInputSection *elf::createCommentSection() {
  return make<MergeInputSection>(SHF_MERGE | SHF_STRINGS, SHT_PROGBITS, 1,
                                 getVersion(), ".comment");
}

// .MIPS.abiflags section.
template <class ELFT>
MipsAbiFlagsSection<ELFT>::MipsAbiFlagsSection(Elf_Mips_ABIFlags Flags)
    : SyntheticSection(SHF_ALLOC, SHT_MIPS_ABIFLAGS, 8, ".MIPS.abiflags"),
      Flags(Flags) {
  this->Entsize = sizeof(Elf_Mips_ABIFlags);
}

template <class ELFT> void MipsAbiFlagsSection<ELFT>::writeTo(uint8_t *Buf) {
  memcpy(Buf, &Flags, sizeof(Flags));
}

template <class ELFT>
MipsAbiFlagsSection<ELFT> *MipsAbiFlagsSection<ELFT>::create() {
  Elf_Mips_ABIFlags Flags = {};
  bool Create = false;

  for (InputSectionBase *Sec : InputSections) {
    if (Sec->Type != SHT_MIPS_ABIFLAGS)
      continue;
    Sec->Live = false;
    Create = true;

    std::string Filename = toString(Sec->File);
    const size_t Size = Sec->data().size();
    // Older version of BFD (such as the default FreeBSD linker) concatenate
    // .MIPS.abiflags instead of merging. To allow for this case (or potential
    // zero padding) we ignore everything after the first Elf_Mips_ABIFlags
    if (Size < sizeof(Elf_Mips_ABIFlags)) {
      error(Filename + ": invalid size of .MIPS.abiflags section: got " +
            Twine(Size) + " instead of " + Twine(sizeof(Elf_Mips_ABIFlags)));
      return nullptr;
    }
    auto *S = reinterpret_cast<const Elf_Mips_ABIFlags *>(Sec->data().data());
    if (S->version != 0) {
      error(Filename + ": unexpected .MIPS.abiflags version " +
            Twine(S->version));
      return nullptr;
    }

    // LLD checks ISA compatibility in calcMipsEFlags(). Here we just
    // select the highest number of ISA/Rev/Ext.
    Flags.isa_level = std::max(Flags.isa_level, S->isa_level);
    Flags.isa_rev = std::max(Flags.isa_rev, S->isa_rev);
    Flags.isa_ext = std::max(Flags.isa_ext, S->isa_ext);
    Flags.gpr_size = std::max(Flags.gpr_size, S->gpr_size);
    Flags.cpr1_size = std::max(Flags.cpr1_size, S->cpr1_size);
    Flags.cpr2_size = std::max(Flags.cpr2_size, S->cpr2_size);
    Flags.ases |= S->ases;
    Flags.flags1 |= S->flags1;
    Flags.flags2 |= S->flags2;
    Flags.fp_abi = elf::getMipsFpAbiFlag(Flags.fp_abi, S->fp_abi, Filename);
  };

  if (Create)
    return make<MipsAbiFlagsSection<ELFT>>(Flags);
  return nullptr;
}

// .MIPS.options section.
template <class ELFT>
MipsOptionsSection<ELFT>::MipsOptionsSection(Elf_Mips_RegInfo Reginfo)
    : SyntheticSection(SHF_ALLOC, SHT_MIPS_OPTIONS, 8, ".MIPS.options"),
      Reginfo(Reginfo) {
  this->Entsize = sizeof(Elf_Mips_Options) + sizeof(Elf_Mips_RegInfo);
}

template <class ELFT> void MipsOptionsSection<ELFT>::writeTo(uint8_t *Buf) {
  auto *Options = reinterpret_cast<Elf_Mips_Options *>(Buf);
  Options->kind = ODK_REGINFO;
  Options->size = getSize();

  if (!Config->Relocatable)
    Reginfo.ri_gp_value = In.MipsGot->getGp();
  memcpy(Buf + sizeof(Elf_Mips_Options), &Reginfo, sizeof(Reginfo));
}

template <class ELFT>
MipsOptionsSection<ELFT> *MipsOptionsSection<ELFT>::create() {
  // N64 ABI only.
  if (!ELFT::Is64Bits)
    return nullptr;

  std::vector<InputSectionBase *> Sections;
  for (InputSectionBase *Sec : InputSections)
    if (Sec->Type == SHT_MIPS_OPTIONS)
      Sections.push_back(Sec);

  if (Sections.empty())
    return nullptr;

  Elf_Mips_RegInfo Reginfo = {};
  for (InputSectionBase *Sec : Sections) {
    Sec->Live = false;

    std::string Filename = toString(Sec->File);
    ArrayRef<uint8_t> D = Sec->data();

    while (!D.empty()) {
      if (D.size() < sizeof(Elf_Mips_Options)) {
        error(Filename + ": invalid size of .MIPS.options section");
        break;
      }

      auto *Opt = reinterpret_cast<const Elf_Mips_Options *>(D.data());
      if (Opt->kind == ODK_REGINFO) {
        Reginfo.ri_gprmask |= Opt->getRegInfo().ri_gprmask;
        Sec->getFile<ELFT>()->MipsGp0 = Opt->getRegInfo().ri_gp_value;
        break;
      }

      if (!Opt->size)
        fatal(Filename + ": zero option descriptor size");
      D = D.slice(Opt->size);
    }
  };

  return make<MipsOptionsSection<ELFT>>(Reginfo);
}

// MIPS .reginfo section.
template <class ELFT>
MipsReginfoSection<ELFT>::MipsReginfoSection(Elf_Mips_RegInfo Reginfo)
    : SyntheticSection(SHF_ALLOC, SHT_MIPS_REGINFO, 4, ".reginfo"),
      Reginfo(Reginfo) {
  this->Entsize = sizeof(Elf_Mips_RegInfo);
}

template <class ELFT> void MipsReginfoSection<ELFT>::writeTo(uint8_t *Buf) {
  if (!Config->Relocatable)
    Reginfo.ri_gp_value = In.MipsGot->getGp();
  memcpy(Buf, &Reginfo, sizeof(Reginfo));
}

template <class ELFT>
MipsReginfoSection<ELFT> *MipsReginfoSection<ELFT>::create() {
  // Section should be alive for O32 and N32 ABIs only.
  if (ELFT::Is64Bits)
    return nullptr;

  std::vector<InputSectionBase *> Sections;
  for (InputSectionBase *Sec : InputSections)
    if (Sec->Type == SHT_MIPS_REGINFO)
      Sections.push_back(Sec);

  if (Sections.empty())
    return nullptr;

  Elf_Mips_RegInfo Reginfo = {};
  for (InputSectionBase *Sec : Sections) {
    Sec->Live = false;

    if (Sec->data().size() != sizeof(Elf_Mips_RegInfo)) {
      error(toString(Sec->File) + ": invalid size of .reginfo section");
      return nullptr;
    }

    auto *R = reinterpret_cast<const Elf_Mips_RegInfo *>(Sec->data().data());
    Reginfo.ri_gprmask |= R->ri_gprmask;
    Sec->getFile<ELFT>()->MipsGp0 = R->ri_gp_value;
  };

  return make<MipsReginfoSection<ELFT>>(Reginfo);
}

InputSection *elf::createInterpSection() {
  // StringSaver guarantees that the returned string ends with '\0'.
  StringRef S = Saver.save(Config->DynamicLinker);
  ArrayRef<uint8_t> Contents = {(const uint8_t *)S.data(), S.size() + 1};

  auto *Sec = make<InputSection>(nullptr, SHF_ALLOC, SHT_PROGBITS, 1, Contents,
                                 ".interp");
  Sec->Live = true;
  return Sec;
}

Defined *elf::addSyntheticLocal(StringRef Name, uint8_t Type, uint64_t Value,
                                uint64_t Size, InputSectionBase &Section) {
  auto *S = make<Defined>(Section.File, Name, STB_LOCAL, STV_DEFAULT, Type,
                          Value, Size, &Section);
  if (In.SymTab)
    In.SymTab->addSymbol(S);
  return S;
}

static size_t getHashSize() {
  switch (Config->BuildId) {
  case BuildIdKind::Fast:
    return 8;
  case BuildIdKind::Md5:
  case BuildIdKind::Uuid:
    return 16;
  case BuildIdKind::Sha1:
    return 20;
  case BuildIdKind::Hexstring:
    return Config->BuildIdVector.size();
  default:
    llvm_unreachable("unknown BuildIdKind");
  }
}

BuildIdSection::BuildIdSection()
    : SyntheticSection(SHF_ALLOC, SHT_NOTE, 4, ".note.gnu.build-id"),
      HashSize(getHashSize()) {}

void BuildIdSection::writeTo(uint8_t *Buf) {
  write32(Buf, 4);                      // Name size
  write32(Buf + 4, HashSize);           // Content size
  write32(Buf + 8, NT_GNU_BUILD_ID);    // Type
  memcpy(Buf + 12, "GNU", 4);           // Name string
  HashBuf = Buf + 16;
}

// Split one uint8 array into small pieces of uint8 arrays.
static std::vector<ArrayRef<uint8_t>> split(ArrayRef<uint8_t> Arr,
                                            size_t ChunkSize) {
  std::vector<ArrayRef<uint8_t>> Ret;
  while (Arr.size() > ChunkSize) {
    Ret.push_back(Arr.take_front(ChunkSize));
    Arr = Arr.drop_front(ChunkSize);
  }
  if (!Arr.empty())
    Ret.push_back(Arr);
  return Ret;
}

// Computes a hash value of Data using a given hash function.
// In order to utilize multiple cores, we first split data into 1MB
// chunks, compute a hash for each chunk, and then compute a hash value
// of the hash values.
void BuildIdSection::computeHash(
    llvm::ArrayRef<uint8_t> Data,
    std::function<void(uint8_t *Dest, ArrayRef<uint8_t> Arr)> HashFn) {
  std::vector<ArrayRef<uint8_t>> Chunks = split(Data, 1024 * 1024);
  std::vector<uint8_t> Hashes(Chunks.size() * HashSize);

  // Compute hash values.
  parallelForEachN(0, Chunks.size(), [&](size_t I) {
    HashFn(Hashes.data() + I * HashSize, Chunks[I]);
  });

  // Write to the final output buffer.
  HashFn(HashBuf, Hashes);
}

BssSection::BssSection(StringRef Name, uint64_t Size, uint32_t Alignment)
    : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_NOBITS, Alignment, Name) {
  this->Bss = true;
  this->Size = Size;
}

void BuildIdSection::writeBuildId(ArrayRef<uint8_t> Buf) {
  switch (Config->BuildId) {
  case BuildIdKind::Fast:
    computeHash(Buf, [](uint8_t *Dest, ArrayRef<uint8_t> Arr) {
      write64le(Dest, xxHash64(Arr));
    });
    break;
  case BuildIdKind::Md5:
    computeHash(Buf, [](uint8_t *Dest, ArrayRef<uint8_t> Arr) {
      memcpy(Dest, MD5::hash(Arr).data(), 16);
    });
    break;
  case BuildIdKind::Sha1:
    computeHash(Buf, [](uint8_t *Dest, ArrayRef<uint8_t> Arr) {
      memcpy(Dest, SHA1::hash(Arr).data(), 20);
    });
    break;
  case BuildIdKind::Uuid:
    if (auto EC = getRandomBytes(HashBuf, HashSize))
      error("entropy source failure: " + EC.message());
    break;
  case BuildIdKind::Hexstring:
    memcpy(HashBuf, Config->BuildIdVector.data(), Config->BuildIdVector.size());
    break;
  default:
    llvm_unreachable("unknown BuildIdKind");
  }
}

EhFrameSection::EhFrameSection()
    : SyntheticSection(SHF_ALLOC, SHT_PROGBITS, 1, ".eh_frame") {}

// Search for an existing CIE record or create a new one.
// CIE records from input object files are uniquified by their contents
// and where their relocations point to.
template <class ELFT, class RelTy>
CieRecord *EhFrameSection::addCie(EhSectionPiece &Cie, ArrayRef<RelTy> Rels) {
  Symbol *Personality = nullptr;
  unsigned FirstRelI = Cie.FirstRelocation;
  if (FirstRelI != (unsigned)-1)
    Personality =
        &Cie.Sec->template getFile<ELFT>()->getRelocTargetSym(Rels[FirstRelI]);

  // Search for an existing CIE by CIE contents/relocation target pair.
  CieRecord *&Rec = CieMap[{Cie.data(), Personality}];

  // If not found, create a new one.
  if (!Rec) {
    Rec = make<CieRecord>();
    Rec->Cie = &Cie;
    CieRecords.push_back(Rec);
  }
  return Rec;
}

// There is one FDE per function. Returns true if a given FDE
// points to a live function.
template <class ELFT, class RelTy>
bool EhFrameSection::isFdeLive(EhSectionPiece &Fde, ArrayRef<RelTy> Rels) {
  auto *Sec = cast<EhInputSection>(Fde.Sec);
  unsigned FirstRelI = Fde.FirstRelocation;

  // An FDE should point to some function because FDEs are to describe
  // functions. That's however not always the case due to an issue of
  // ld.gold with -r. ld.gold may discard only functions and leave their
  // corresponding FDEs, which results in creating bad .eh_frame sections.
  // To deal with that, we ignore such FDEs.
  if (FirstRelI == (unsigned)-1)
    return false;

  const RelTy &Rel = Rels[FirstRelI];
  Symbol &B = Sec->template getFile<ELFT>()->getRelocTargetSym(Rel);

  // FDEs for garbage-collected or merged-by-ICF sections are dead.
  if (auto *D = dyn_cast<Defined>(&B))
    if (SectionBase *Sec = D->Section)
      return Sec->Live;
  return false;
}

// .eh_frame is a sequence of CIE or FDE records. In general, there
// is one CIE record per input object file which is followed by
// a list of FDEs. This function searches an existing CIE or create a new
// one and associates FDEs to the CIE.
template <class ELFT, class RelTy>
void EhFrameSection::addSectionAux(EhInputSection *Sec, ArrayRef<RelTy> Rels) {
  OffsetToCie.clear();
  for (EhSectionPiece &Piece : Sec->Pieces) {
    // The empty record is the end marker.
    if (Piece.Size == 4)
      return;

    size_t Offset = Piece.InputOff;
    uint32_t ID = read32(Piece.data().data() + 4);
    if (ID == 0) {
      OffsetToCie[Offset] = addCie<ELFT>(Piece, Rels);
      continue;
    }

    uint32_t CieOffset = Offset + 4 - ID;
    CieRecord *Rec = OffsetToCie[CieOffset];
    if (!Rec)
      fatal(toString(Sec) + ": invalid CIE reference");

    if (!isFdeLive<ELFT>(Piece, Rels))
      continue;
    Rec->Fdes.push_back(&Piece);
    NumFdes++;
  }
}

template <class ELFT> void EhFrameSection::addSection(InputSectionBase *C) {
  auto *Sec = cast<EhInputSection>(C);
  Sec->Parent = this;

  Alignment = std::max(Alignment, Sec->Alignment);
  Sections.push_back(Sec);

  for (auto *DS : Sec->DependentSections)
    DependentSections.push_back(DS);

  if (Sec->Pieces.empty())
    return;

  if (Sec->AreRelocsRela)
    addSectionAux<ELFT>(Sec, Sec->template relas<ELFT>());
  else
    addSectionAux<ELFT>(Sec, Sec->template rels<ELFT>());
}

static void writeCieFde(uint8_t *Buf, ArrayRef<uint8_t> D) {
  memcpy(Buf, D.data(), D.size());

  size_t Aligned = alignTo(D.size(), Config->Wordsize);

  // Zero-clear trailing padding if it exists.
  memset(Buf + D.size(), 0, Aligned - D.size());

  // Fix the size field. -4 since size does not include the size field itself.
  write32(Buf, Aligned - 4);
}

void EhFrameSection::finalizeContents() {
  assert(!this->Size); // Not finalized.
  size_t Off = 0;
  for (CieRecord *Rec : CieRecords) {
    Rec->Cie->OutputOff = Off;
    Off += alignTo(Rec->Cie->Size, Config->Wordsize);

    for (EhSectionPiece *Fde : Rec->Fdes) {
      Fde->OutputOff = Off;
      Off += alignTo(Fde->Size, Config->Wordsize);
    }
  }

  // The LSB standard does not allow a .eh_frame section with zero
  // Call Frame Information records. glibc unwind-dw2-fde.c
  // classify_object_over_fdes expects there is a CIE record length 0 as a
  // terminator. Thus we add one unconditionally.
  Off += 4;

  this->Size = Off;
}

// Returns data for .eh_frame_hdr. .eh_frame_hdr is a binary search table
// to get an FDE from an address to which FDE is applied. This function
// returns a list of such pairs.
std::vector<EhFrameSection::FdeData> EhFrameSection::getFdeData() const {
  uint8_t *Buf = Out::BufferStart + getParent()->Offset + OutSecOff;
  std::vector<FdeData> Ret;

  uint64_t VA = In.EhFrameHdr->getVA();
  for (CieRecord *Rec : CieRecords) {
    uint8_t Enc = getFdeEncoding(Rec->Cie);
    for (EhSectionPiece *Fde : Rec->Fdes) {
      uint64_t Pc = getFdePc(Buf, Fde->OutputOff, Enc);
      uint64_t FdeVA = getParent()->Addr + Fde->OutputOff;
      if (!isInt<32>(Pc - VA))
        fatal(toString(Fde->Sec) + ": PC offset is too large: 0x" +
              Twine::utohexstr(Pc - VA));
      Ret.push_back({uint32_t(Pc - VA), uint32_t(FdeVA - VA)});
    }
  }

  // Sort the FDE list by their PC and uniqueify. Usually there is only
  // one FDE for a PC (i.e. function), but if ICF merges two functions
  // into one, there can be more than one FDEs pointing to the address.
  auto Less = [](const FdeData &A, const FdeData &B) {
    return A.PcRel < B.PcRel;
  };
  std::stable_sort(Ret.begin(), Ret.end(), Less);
  auto Eq = [](const FdeData &A, const FdeData &B) {
    return A.PcRel == B.PcRel;
  };
  Ret.erase(std::unique(Ret.begin(), Ret.end(), Eq), Ret.end());

  return Ret;
}

static uint64_t readFdeAddr(uint8_t *Buf, int Size) {
  switch (Size) {
  case DW_EH_PE_udata2:
    return read16(Buf);
  case DW_EH_PE_sdata2:
    return (int16_t)read16(Buf);
  case DW_EH_PE_udata4:
    return read32(Buf);
  case DW_EH_PE_sdata4:
    return (int32_t)read32(Buf);
  case DW_EH_PE_udata8:
  case DW_EH_PE_sdata8:
    return read64(Buf);
  case DW_EH_PE_absptr:
    return readUint(Buf);
  }
  fatal("unknown FDE size encoding");
}

// Returns the VA to which a given FDE (on a mmap'ed buffer) is applied to.
// We need it to create .eh_frame_hdr section.
uint64_t EhFrameSection::getFdePc(uint8_t *Buf, size_t FdeOff,
                                  uint8_t Enc) const {
  // The starting address to which this FDE applies is
  // stored at FDE + 8 byte.
  size_t Off = FdeOff + 8;
  uint64_t Addr = readFdeAddr(Buf + Off, Enc & 0xf);
  if ((Enc & 0x70) == DW_EH_PE_absptr)
    return Addr;
  if ((Enc & 0x70) == DW_EH_PE_pcrel)
    return Addr + getParent()->Addr + Off;
  fatal("unknown FDE size relative encoding");
}

void EhFrameSection::writeTo(uint8_t *Buf) {
  // Write CIE and FDE records.
  for (CieRecord *Rec : CieRecords) {
    size_t CieOffset = Rec->Cie->OutputOff;
    writeCieFde(Buf + CieOffset, Rec->Cie->data());

    for (EhSectionPiece *Fde : Rec->Fdes) {
      size_t Off = Fde->OutputOff;
      writeCieFde(Buf + Off, Fde->data());

      // FDE's second word should have the offset to an associated CIE.
      // Write it.
      write32(Buf + Off + 4, Off + 4 - CieOffset);
    }
  }

  // Apply relocations. .eh_frame section contents are not contiguous
  // in the output buffer, but relocateAlloc() still works because
  // getOffset() takes care of discontiguous section pieces.
  for (EhInputSection *S : Sections)
    S->relocateAlloc(Buf, nullptr);

  if (In.EhFrameHdr && In.EhFrameHdr->getParent())
    In.EhFrameHdr->write();
}

GotSection::GotSection()
    : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS,
                       Target->GotEntrySize, ".got") {
  // PPC64 saves the ElfSym::GlobalOffsetTable .TOC. as the first entry in the
  // .got. If there are no references to .TOC. in the symbol table,
  // ElfSym::GlobalOffsetTable will not be defined and we won't need to save
  // .TOC. in the .got. When it is defined, we increase NumEntries by the number
  // of entries used to emit ElfSym::GlobalOffsetTable.
  if (ElfSym::GlobalOffsetTable && !Target->GotBaseSymInGotPlt)
    NumEntries += Target->GotHeaderEntriesNum;
}

void GotSection::addEntry(Symbol &Sym) {
  Sym.GotIndex = NumEntries;
  ++NumEntries;
}

bool GotSection::addDynTlsEntry(Symbol &Sym) {
  if (Sym.GlobalDynIndex != -1U)
    return false;
  Sym.GlobalDynIndex = NumEntries;
  // Global Dynamic TLS entries take two GOT slots.
  NumEntries += 2;
  return true;
}

// Reserves TLS entries for a TLS module ID and a TLS block offset.
// In total it takes two GOT slots.
bool GotSection::addTlsIndex() {
  if (TlsIndexOff != uint32_t(-1))
    return false;
  TlsIndexOff = NumEntries * Config->Wordsize;
  NumEntries += 2;
  return true;
}

uint64_t GotSection::getGlobalDynAddr(const Symbol &B) const {
  return this->getVA() + B.GlobalDynIndex * Config->Wordsize;
}

uint64_t GotSection::getGlobalDynOffset(const Symbol &B) const {
  return B.GlobalDynIndex * Config->Wordsize;
}

void GotSection::finalizeContents() {
  Size = NumEntries * Config->Wordsize;
}

bool GotSection::empty() const {
  // We need to emit a GOT even if it's empty if there's a relocation that is
  // relative to GOT(such as GOTOFFREL).
  return NumEntries == 0 && !HasGotOffRel;
}

void GotSection::writeTo(uint8_t *Buf) {
  // Buf points to the start of this section's buffer,
  // whereas InputSectionBase::relocateAlloc() expects its argument
  // to point to the start of the output section.
  Target->writeGotHeader(Buf);
  relocateAlloc(Buf - OutSecOff, Buf - OutSecOff + Size);
}

static uint64_t getMipsPageAddr(uint64_t Addr) {
  return (Addr + 0x8000) & ~0xffff;
}

static uint64_t getMipsPageCount(uint64_t Size) {
  return (Size + 0xfffe) / 0xffff + 1;
}

MipsGotSection::MipsGotSection()
    : SyntheticSection(SHF_ALLOC | SHF_WRITE | SHF_MIPS_GPREL, SHT_PROGBITS, 16,
                       ".got") {}

void MipsGotSection::addEntry(InputFile &File, Symbol &Sym, int64_t Addend,
                              RelExpr Expr) {
  FileGot &G = getGot(File);
  if (Expr == R_MIPS_GOT_LOCAL_PAGE) {
    if (const OutputSection *OS = Sym.getOutputSection())
      G.PagesMap.insert({OS, {}});
    else
      G.Local16.insert({{nullptr, getMipsPageAddr(Sym.getVA(Addend))}, 0});
  } else if (Sym.isTls())
    G.Tls.insert({&Sym, 0});
  else if (Sym.IsPreemptible && Expr == R_ABS)
    G.Relocs.insert({&Sym, 0});
  else if (Sym.IsPreemptible)
    G.Global.insert({&Sym, 0});
  else if (Expr == R_MIPS_GOT_OFF32)
    G.Local32.insert({{&Sym, Addend}, 0});
  else
    G.Local16.insert({{&Sym, Addend}, 0});
}

void MipsGotSection::addDynTlsEntry(InputFile &File, Symbol &Sym) {
  getGot(File).DynTlsSymbols.insert({&Sym, 0});
}

void MipsGotSection::addTlsIndex(InputFile &File) {
  getGot(File).DynTlsSymbols.insert({nullptr, 0});
}

size_t MipsGotSection::FileGot::getEntriesNum() const {
  return getPageEntriesNum() + Local16.size() + Global.size() + Relocs.size() +
         Tls.size() + DynTlsSymbols.size() * 2;
}

size_t MipsGotSection::FileGot::getPageEntriesNum() const {
  size_t Num = 0;
  for (const std::pair<const OutputSection *, FileGot::PageBlock> &P : PagesMap)
    Num += P.second.Count;
  return Num;
}

size_t MipsGotSection::FileGot::getIndexedEntriesNum() const {
  size_t Count = getPageEntriesNum() + Local16.size() + Global.size();
  // If there are relocation-only entries in the GOT, TLS entries
  // are allocated after them. TLS entries should be addressable
  // by 16-bit index so count both reloc-only and TLS entries.
  if (!Tls.empty() || !DynTlsSymbols.empty())
    Count += Relocs.size() + Tls.size() + DynTlsSymbols.size() * 2;
  return Count;
}

MipsGotSection::FileGot &MipsGotSection::getGot(InputFile &F) {
  if (!F.MipsGotIndex.hasValue()) {
    Gots.emplace_back();
    Gots.back().File = &F;
    F.MipsGotIndex = Gots.size() - 1;
  }
  return Gots[*F.MipsGotIndex];
}

uint64_t MipsGotSection::getPageEntryOffset(const InputFile *F,
                                            const Symbol &Sym,
                                            int64_t Addend) const {
  const FileGot &G = Gots[*F->MipsGotIndex];
  uint64_t Index = 0;
  if (const OutputSection *OutSec = Sym.getOutputSection()) {
    uint64_t SecAddr = getMipsPageAddr(OutSec->Addr);
    uint64_t SymAddr = getMipsPageAddr(Sym.getVA(Addend));
    Index = G.PagesMap.lookup(OutSec).FirstIndex + (SymAddr - SecAddr) / 0xffff;
  } else {
    Index = G.Local16.lookup({nullptr, getMipsPageAddr(Sym.getVA(Addend))});
  }
  return Index * Config->Wordsize;
}

uint64_t MipsGotSection::getSymEntryOffset(const InputFile *F, const Symbol &S,
                                           int64_t Addend) const {
  const FileGot &G = Gots[*F->MipsGotIndex];
  Symbol *Sym = const_cast<Symbol *>(&S);
  if (Sym->isTls())
    return G.Tls.lookup(Sym) * Config->Wordsize;
  if (Sym->IsPreemptible)
    return G.Global.lookup(Sym) * Config->Wordsize;
  return G.Local16.lookup({Sym, Addend}) * Config->Wordsize;
}

uint64_t MipsGotSection::getTlsIndexOffset(const InputFile *F) const {
  const FileGot &G = Gots[*F->MipsGotIndex];
  return G.DynTlsSymbols.lookup(nullptr) * Config->Wordsize;
}

uint64_t MipsGotSection::getGlobalDynOffset(const InputFile *F,
                                            const Symbol &S) const {
  const FileGot &G = Gots[*F->MipsGotIndex];
  Symbol *Sym = const_cast<Symbol *>(&S);
  return G.DynTlsSymbols.lookup(Sym) * Config->Wordsize;
}

const Symbol *MipsGotSection::getFirstGlobalEntry() const {
  if (Gots.empty())
    return nullptr;
  const FileGot &PrimGot = Gots.front();
  if (!PrimGot.Global.empty())
    return PrimGot.Global.front().first;
  if (!PrimGot.Relocs.empty())
    return PrimGot.Relocs.front().first;
  return nullptr;
}

unsigned MipsGotSection::getLocalEntriesNum() const {
  if (Gots.empty())
    return HeaderEntriesNum;
  return HeaderEntriesNum + Gots.front().getPageEntriesNum() +
         Gots.front().Local16.size();
}

bool MipsGotSection::tryMergeGots(FileGot &Dst, FileGot &Src, bool IsPrimary) {
  FileGot Tmp = Dst;
  set_union(Tmp.PagesMap, Src.PagesMap);
  set_union(Tmp.Local16, Src.Local16);
  set_union(Tmp.Global, Src.Global);
  set_union(Tmp.Relocs, Src.Relocs);
  set_union(Tmp.Tls, Src.Tls);
  set_union(Tmp.DynTlsSymbols, Src.DynTlsSymbols);

  size_t Count = IsPrimary ? HeaderEntriesNum : 0;
  Count += Tmp.getIndexedEntriesNum();

  if (Count * Config->Wordsize > Config->MipsGotSize)
    return false;

  std::swap(Tmp, Dst);
  return true;
}

void MipsGotSection::finalizeContents() { updateAllocSize(); }

bool MipsGotSection::updateAllocSize() {
  Size = HeaderEntriesNum * Config->Wordsize;
  for (const FileGot &G : Gots)
    Size += G.getEntriesNum() * Config->Wordsize;
  return false;
}

void MipsGotSection::build() {
  if (Gots.empty())
    return;

  std::vector<FileGot> MergedGots(1);

  // For each GOT move non-preemptible symbols from the `Global`
  // to `Local16` list. Preemptible symbol might become non-preemptible
  // one if, for example, it gets a related copy relocation.
  for (FileGot &Got : Gots) {
    for (auto &P: Got.Global)
      if (!P.first->IsPreemptible)
        Got.Local16.insert({{P.first, 0}, 0});
    Got.Global.remove_if([&](const std::pair<Symbol *, size_t> &P) {
      return !P.first->IsPreemptible;
    });
  }

  // For each GOT remove "reloc-only" entry if there is "global"
  // entry for the same symbol. And add local entries which indexed
  // using 32-bit value at the end of 16-bit entries.
  for (FileGot &Got : Gots) {
    Got.Relocs.remove_if([&](const std::pair<Symbol *, size_t> &P) {
      return Got.Global.count(P.first);
    });
    set_union(Got.Local16, Got.Local32);
    Got.Local32.clear();
  }

  // Evaluate number of "reloc-only" entries in the resulting GOT.
  // To do that put all unique "reloc-only" and "global" entries
  // from all GOTs to the future primary GOT.
  FileGot *PrimGot = &MergedGots.front();
  for (FileGot &Got : Gots) {
    set_union(PrimGot->Relocs, Got.Global);
    set_union(PrimGot->Relocs, Got.Relocs);
    Got.Relocs.clear();
  }

  // Evaluate number of "page" entries in each GOT.
  for (FileGot &Got : Gots) {
    for (std::pair<const OutputSection *, FileGot::PageBlock> &P :
         Got.PagesMap) {
      const OutputSection *OS = P.first;
      uint64_t SecSize = 0;
      for (BaseCommand *Cmd : OS->SectionCommands) {
        if (auto *ISD = dyn_cast<InputSectionDescription>(Cmd))
          for (InputSection *IS : ISD->Sections) {
            uint64_t Off = alignTo(SecSize, IS->Alignment);
            SecSize = Off + IS->getSize();
          }
      }
      P.second.Count = getMipsPageCount(SecSize);
    }
  }

  // Merge GOTs. Try to join as much as possible GOTs but do not exceed
  // maximum GOT size. At first, try to fill the primary GOT because
  // the primary GOT can be accessed in the most effective way. If it
  // is not possible, try to fill the last GOT in the list, and finally
  // create a new GOT if both attempts failed.
  for (FileGot &SrcGot : Gots) {
    InputFile *File = SrcGot.File;
    if (tryMergeGots(MergedGots.front(), SrcGot, true)) {
      File->MipsGotIndex = 0;
    } else {
      // If this is the first time we failed to merge with the primary GOT,
      // MergedGots.back() will also be the primary GOT. We must make sure not
      // to try to merge again with IsPrimary=false, as otherwise, if the
      // inputs are just right, we could allow the primary GOT to become 1 or 2
      // words too big due to ignoring the header size.
      if (MergedGots.size() == 1 ||
          !tryMergeGots(MergedGots.back(), SrcGot, false)) {
        MergedGots.emplace_back();
        std::swap(MergedGots.back(), SrcGot);
      }
      File->MipsGotIndex = MergedGots.size() - 1;
    }
  }
  std::swap(Gots, MergedGots);

  // Reduce number of "reloc-only" entries in the primary GOT
  // by substracting "global" entries exist in the primary GOT.
  PrimGot = &Gots.front();
  PrimGot->Relocs.remove_if([&](const std::pair<Symbol *, size_t> &P) {
    return PrimGot->Global.count(P.first);
  });

  // Calculate indexes for each GOT entry.
  size_t Index = HeaderEntriesNum;
  for (FileGot &Got : Gots) {
    Got.StartIndex = &Got == PrimGot ? 0 : Index;
    for (std::pair<const OutputSection *, FileGot::PageBlock> &P :
         Got.PagesMap) {
      // For each output section referenced by GOT page relocations calculate
      // and save into PagesMap an upper bound of MIPS GOT entries required
      // to store page addresses of local symbols. We assume the worst case -
      // each 64kb page of the output section has at least one GOT relocation
      // against it. And take in account the case when the section intersects
      // page boundaries.
      P.second.FirstIndex = Index;
      Index += P.second.Count;
    }
    for (auto &P: Got.Local16)
      P.second = Index++;
    for (auto &P: Got.Global)
      P.second = Index++;
    for (auto &P: Got.Relocs)
      P.second = Index++;
    for (auto &P: Got.Tls)
      P.second = Index++;
    for (auto &P: Got.DynTlsSymbols) {
      P.second = Index;
      Index += 2;
    }
  }

  // Update Symbol::GotIndex field to use this
  // value later in the `sortMipsSymbols` function.
  for (auto &P : PrimGot->Global)
    P.first->GotIndex = P.second;
  for (auto &P : PrimGot->Relocs)
    P.first->GotIndex = P.second;

  // Create dynamic relocations.
  for (FileGot &Got : Gots) {
    // Create dynamic relocations for TLS entries.
    for (std::pair<Symbol *, size_t> &P : Got.Tls) {
      Symbol *S = P.first;
      uint64_t Offset = P.second * Config->Wordsize;
      if (S->IsPreemptible)
        In.RelaDyn->addReloc(Target->TlsGotRel, this, Offset, S);
    }
    for (std::pair<Symbol *, size_t> &P : Got.DynTlsSymbols) {
      Symbol *S = P.first;
      uint64_t Offset = P.second * Config->Wordsize;
      if (S == nullptr) {
        if (!Config->Pic)
          continue;
        In.RelaDyn->addReloc(Target->TlsModuleIndexRel, this, Offset, S);
      } else {
        // When building a shared library we still need a dynamic relocation
        // for the module index. Therefore only checking for
        // S->IsPreemptible is not sufficient (this happens e.g. for
        // thread-locals that have been marked as local through a linker script)
        if (!S->IsPreemptible && !Config->Pic)
          continue;
        In.RelaDyn->addReloc(Target->TlsModuleIndexRel, this, Offset, S);
        // However, we can skip writing the TLS offset reloc for non-preemptible
        // symbols since it is known even in shared libraries
        if (!S->IsPreemptible)
          continue;
        Offset += Config->Wordsize;
        In.RelaDyn->addReloc(Target->TlsOffsetRel, this, Offset, S);
      }
    }

    // Do not create dynamic relocations for non-TLS
    // entries in the primary GOT.
    if (&Got == PrimGot)
      continue;

    // Dynamic relocations for "global" entries.
    for (const std::pair<Symbol *, size_t> &P : Got.Global) {
      uint64_t Offset = P.second * Config->Wordsize;
      In.RelaDyn->addReloc(Target->RelativeRel, this, Offset, P.first);
    }
    if (!Config->Pic)
      continue;
    // Dynamic relocations for "local" entries in case of PIC.
    for (const std::pair<const OutputSection *, FileGot::PageBlock> &L :
         Got.PagesMap) {
      size_t PageCount = L.second.Count;
      for (size_t PI = 0; PI < PageCount; ++PI) {
        uint64_t Offset = (L.second.FirstIndex + PI) * Config->Wordsize;
        In.RelaDyn->addReloc({Target->RelativeRel, this, Offset, L.first,
                              int64_t(PI * 0x10000)});
      }
    }
    for (const std::pair<GotEntry, size_t> &P : Got.Local16) {
      uint64_t Offset = P.second * Config->Wordsize;
      In.RelaDyn->addReloc({Target->RelativeRel, this, Offset, true,
                            P.first.first, P.first.second});
    }
  }
}

bool MipsGotSection::empty() const {
  // We add the .got section to the result for dynamic MIPS target because
  // its address and properties are mentioned in the .dynamic section.
  return Config->Relocatable;
}

uint64_t MipsGotSection::getGp(const InputFile *F) const {
  // For files without related GOT or files refer a primary GOT
  // returns "common" _gp value. For secondary GOTs calculate
  // individual _gp values.
  if (!F || !F->MipsGotIndex.hasValue() || *F->MipsGotIndex == 0)
    return ElfSym::MipsGp->getVA(0);
  return getVA() + Gots[*F->MipsGotIndex].StartIndex * Config->Wordsize +
         0x7ff0;
}

void MipsGotSection::writeTo(uint8_t *Buf) {
  // Set the MSB of the second GOT slot. This is not required by any
  // MIPS ABI documentation, though.
  //
  // There is a comment in glibc saying that "The MSB of got[1] of a
  // gnu object is set to identify gnu objects," and in GNU gold it
  // says "the second entry will be used by some runtime loaders".
  // But how this field is being used is unclear.
  //
  // We are not really willing to mimic other linkers behaviors
  // without understanding why they do that, but because all files
  // generated by GNU tools have this special GOT value, and because
  // we've been doing this for years, it is probably a safe bet to
  // keep doing this for now. We really need to revisit this to see
  // if we had to do this.
  writeUint(Buf + Config->Wordsize, (uint64_t)1 << (Config->Wordsize * 8 - 1));
  for (const FileGot &G : Gots) {
    auto Write = [&](size_t I, const Symbol *S, int64_t A) {
      uint64_t VA = A;
      if (S)
        VA = S->getVA(A);
      writeUint(Buf + I * Config->Wordsize, VA);
    };
    // Write 'page address' entries to the local part of the GOT.
    for (const std::pair<const OutputSection *, FileGot::PageBlock> &L :
         G.PagesMap) {
      size_t PageCount = L.second.Count;
      uint64_t FirstPageAddr = getMipsPageAddr(L.first->Addr);
      for (size_t PI = 0; PI < PageCount; ++PI)
        Write(L.second.FirstIndex + PI, nullptr, FirstPageAddr + PI * 0x10000);
    }
    // Local, global, TLS, reloc-only  entries.
    // If TLS entry has a corresponding dynamic relocations, leave it
    // initialized by zero. Write down adjusted TLS symbol's values otherwise.
    // To calculate the adjustments use offsets for thread-local storage.
    // https://www.linux-mips.org/wiki/NPTL
    for (const std::pair<GotEntry, size_t> &P : G.Local16)
      Write(P.second, P.first.first, P.first.second);
    // Write VA to the primary GOT only. For secondary GOTs that
    // will be done by REL32 dynamic relocations.
    if (&G == &Gots.front())
      for (const std::pair<const Symbol *, size_t> &P : G.Global)
        Write(P.second, P.first, 0);
    for (const std::pair<Symbol *, size_t> &P : G.Relocs)
      Write(P.second, P.first, 0);
    for (const std::pair<Symbol *, size_t> &P : G.Tls)
      Write(P.second, P.first, P.first->IsPreemptible ? 0 : -0x7000);
    for (const std::pair<Symbol *, size_t> &P : G.DynTlsSymbols) {
      if (P.first == nullptr && !Config->Pic)
        Write(P.second, nullptr, 1);
      else if (P.first && !P.first->IsPreemptible) {
        // If we are emitting PIC code with relocations we mustn't write
        // anything to the GOT here. When using Elf_Rel relocations the value
        // one will be treated as an addend and will cause crashes at runtime
        if (!Config->Pic)
          Write(P.second, nullptr, 1);
        Write(P.second + 1, P.first, -0x8000);
      }
    }
  }
}

// On PowerPC the .plt section is used to hold the table of function addresses
// instead of the .got.plt, and the type is SHT_NOBITS similar to a .bss
// section. I don't know why we have a BSS style type for the section but it is
// consitent across both 64-bit PowerPC ABIs as well as the 32-bit PowerPC ABI.
GotPltSection::GotPltSection()
    : SyntheticSection(SHF_ALLOC | SHF_WRITE,
                       Config->EMachine == EM_PPC64 ? SHT_NOBITS : SHT_PROGBITS,
                       Target->GotPltEntrySize,
                       Config->EMachine == EM_PPC64 ? ".plt" : ".got.plt") {}

void GotPltSection::addEntry(Symbol &Sym) {
  assert(Sym.PltIndex == Entries.size());
  Entries.push_back(&Sym);
}

size_t GotPltSection::getSize() const {
  return (Target->GotPltHeaderEntriesNum + Entries.size()) *
         Target->GotPltEntrySize;
}

void GotPltSection::writeTo(uint8_t *Buf) {
  Target->writeGotPltHeader(Buf);
  Buf += Target->GotPltHeaderEntriesNum * Target->GotPltEntrySize;
  for (const Symbol *B : Entries) {
    Target->writeGotPlt(Buf, *B);
    Buf += Config->Wordsize;
  }
}

bool GotPltSection::empty() const {
  // We need to emit GOTPLT even if it's empty if there's a relocation relative
  // to it.
  return Entries.empty() && !HasGotPltOffRel;
}

static StringRef getIgotPltName() {
  // On ARM the IgotPltSection is part of the GotSection.
  if (Config->EMachine == EM_ARM)
    return ".got";

  // On PowerPC64 the GotPltSection is renamed to '.plt' so the IgotPltSection
  // needs to be named the same.
  if (Config->EMachine == EM_PPC64)
    return ".plt";

  return ".got.plt";
}

// On PowerPC64 the GotPltSection type is SHT_NOBITS so we have to follow suit
// with the IgotPltSection.
IgotPltSection::IgotPltSection()
    : SyntheticSection(SHF_ALLOC | SHF_WRITE,
                       Config->EMachine == EM_PPC64 ? SHT_NOBITS : SHT_PROGBITS,
                       Target->GotPltEntrySize, getIgotPltName()) {}

void IgotPltSection::addEntry(Symbol &Sym) {
  assert(Sym.PltIndex == Entries.size());
  Entries.push_back(&Sym);
}

size_t IgotPltSection::getSize() const {
  return Entries.size() * Target->GotPltEntrySize;
}

void IgotPltSection::writeTo(uint8_t *Buf) {
  for (const Symbol *B : Entries) {
    Target->writeIgotPlt(Buf, *B);
    Buf += Config->Wordsize;
  }
}

StringTableSection::StringTableSection(StringRef Name, bool Dynamic)
    : SyntheticSection(Dynamic ? (uint64_t)SHF_ALLOC : 0, SHT_STRTAB, 1, Name),
      Dynamic(Dynamic) {
  // ELF string tables start with a NUL byte.
  addString("");
}

// Adds a string to the string table. If HashIt is true we hash and check for
// duplicates. It is optional because the name of global symbols are already
// uniqued and hashing them again has a big cost for a small value: uniquing
// them with some other string that happens to be the same.
unsigned StringTableSection::addString(StringRef S, bool HashIt) {
  if (HashIt) {
    auto R = StringMap.insert(std::make_pair(S, this->Size));
    if (!R.second)
      return R.first->second;
  }
  unsigned Ret = this->Size;
  this->Size = this->Size + S.size() + 1;
  Strings.push_back(S);
  return Ret;
}

void StringTableSection::writeTo(uint8_t *Buf) {
  for (StringRef S : Strings) {
    memcpy(Buf, S.data(), S.size());
    Buf[S.size()] = '\0';
    Buf += S.size() + 1;
  }
}

// Returns the number of version definition entries. Because the first entry
// is for the version definition itself, it is the number of versioned symbols
// plus one. Note that we don't support multiple versions yet.
static unsigned getVerDefNum() { return Config->VersionDefinitions.size() + 1; }

template <class ELFT>
DynamicSection<ELFT>::DynamicSection()
    : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_DYNAMIC, Config->Wordsize,
                       ".dynamic") {
  this->Entsize = ELFT::Is64Bits ? 16 : 8;

  // .dynamic section is not writable on MIPS and on Fuchsia OS
  // which passes -z rodynamic.
  // See "Special Section" in Chapter 4 in the following document:
  // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
  if (Config->EMachine == EM_MIPS || Config->ZRodynamic)
    this->Flags = SHF_ALLOC;
}

template <class ELFT>
void DynamicSection<ELFT>::add(int32_t Tag, std::function<uint64_t()> Fn) {
  Entries.push_back({Tag, Fn});
}

template <class ELFT>
void DynamicSection<ELFT>::addInt(int32_t Tag, uint64_t Val) {
  Entries.push_back({Tag, [=] { return Val; }});
}

template <class ELFT>
void DynamicSection<ELFT>::addInSec(int32_t Tag, InputSection *Sec) {
  Entries.push_back({Tag, [=] { return Sec->getVA(0); }});
}

template <class ELFT>
void DynamicSection<ELFT>::addInSecRelative(int32_t Tag, InputSection *Sec) {
  size_t TagOffset = Entries.size() * Entsize;
  Entries.push_back(
      {Tag, [=] { return Sec->getVA(0) - (getVA() + TagOffset); }});
}

template <class ELFT>
void DynamicSection<ELFT>::addOutSec(int32_t Tag, OutputSection *Sec) {
  Entries.push_back({Tag, [=] { return Sec->Addr; }});
}

template <class ELFT>
void DynamicSection<ELFT>::addSize(int32_t Tag, OutputSection *Sec) {
  Entries.push_back({Tag, [=] { return Sec->Size; }});
}

template <class ELFT>
void DynamicSection<ELFT>::addSym(int32_t Tag, Symbol *Sym) {
  Entries.push_back({Tag, [=] { return Sym->getVA(); }});
}

// A Linker script may assign the RELA relocation sections to the same
// output section. When this occurs we cannot just use the OutputSection
// Size. Moreover the [DT_JMPREL, DT_JMPREL + DT_PLTRELSZ) is permitted to
// overlap with the [DT_RELA, DT_RELA + DT_RELASZ).
static uint64_t addPltRelSz() {
  size_t Size = In.RelaPlt->getSize();
  if (In.RelaIplt->getParent() == In.RelaPlt->getParent() &&
      In.RelaIplt->Name == In.RelaPlt->Name)
    Size += In.RelaIplt->getSize();
  return Size;
}

// Add remaining entries to complete .dynamic contents.
template <class ELFT> void DynamicSection<ELFT>::finalizeContents() {
  for (StringRef S : Config->FilterList)
    addInt(DT_FILTER, In.DynStrTab->addString(S));
  for (StringRef S : Config->AuxiliaryList)
    addInt(DT_AUXILIARY, In.DynStrTab->addString(S));

  if (!Config->Rpath.empty())
    addInt(Config->EnableNewDtags ? DT_RUNPATH : DT_RPATH,
           In.DynStrTab->addString(Config->Rpath));

  for (InputFile *File : SharedFiles) {
    SharedFile<ELFT> *F = cast<SharedFile<ELFT>>(File);
    if (F->IsNeeded)
      addInt(DT_NEEDED, In.DynStrTab->addString(F->SoName));
  }
  if (!Config->SoName.empty())
    addInt(DT_SONAME, In.DynStrTab->addString(Config->SoName));

  // Set DT_FLAGS and DT_FLAGS_1.
  uint32_t DtFlags = 0;
  uint32_t DtFlags1 = 0;
  if (Config->Bsymbolic)
    DtFlags |= DF_SYMBOLIC;
  if (Config->ZGlobal)
    DtFlags1 |= DF_1_GLOBAL;
  if (Config->ZInitfirst)
    DtFlags1 |= DF_1_INITFIRST;
  if (Config->ZInterpose)
    DtFlags1 |= DF_1_INTERPOSE;
  if (Config->ZNodefaultlib)
    DtFlags1 |= DF_1_NODEFLIB;
  if (Config->ZNodelete)
    DtFlags1 |= DF_1_NODELETE;
  if (Config->ZNodlopen)
    DtFlags1 |= DF_1_NOOPEN;
  if (Config->ZNow) {
    DtFlags |= DF_BIND_NOW;
    DtFlags1 |= DF_1_NOW;
  }
  if (Config->ZOrigin) {
    DtFlags |= DF_ORIGIN;
    DtFlags1 |= DF_1_ORIGIN;
  }
  if (!Config->ZText)
    DtFlags |= DF_TEXTREL;
  if (Config->HasStaticTlsModel)
    DtFlags |= DF_STATIC_TLS;

  if (DtFlags)
    addInt(DT_FLAGS, DtFlags);
  if (DtFlags1)
    addInt(DT_FLAGS_1, DtFlags1);

  // DT_DEBUG is a pointer to debug informaion used by debuggers at runtime. We
  // need it for each process, so we don't write it for DSOs. The loader writes
  // the pointer into this entry.
  //
  // DT_DEBUG is the only .dynamic entry that needs to be written to. Some
  // systems (currently only Fuchsia OS) provide other means to give the
  // debugger this information. Such systems may choose make .dynamic read-only.
  // If the target is such a system (used -z rodynamic) don't write DT_DEBUG.
  if (!Config->Shared && !Config->Relocatable && !Config->ZRodynamic)
    addInt(DT_DEBUG, 0);

  if (OutputSection *Sec = In.DynStrTab->getParent())
    this->Link = Sec->SectionIndex;

  if (!In.RelaDyn->empty()) {
    addInSec(In.RelaDyn->DynamicTag, In.RelaDyn);
    addSize(In.RelaDyn->SizeDynamicTag, In.RelaDyn->getParent());

    bool IsRela = Config->IsRela;
    addInt(IsRela ? DT_RELAENT : DT_RELENT,
           IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel));

    // MIPS dynamic loader does not support RELCOUNT tag.
    // The problem is in the tight relation between dynamic
    // relocations and GOT. So do not emit this tag on MIPS.
    if (Config->EMachine != EM_MIPS) {
      size_t NumRelativeRels = In.RelaDyn->getRelativeRelocCount();
      if (Config->ZCombreloc && NumRelativeRels)
        addInt(IsRela ? DT_RELACOUNT : DT_RELCOUNT, NumRelativeRels);
    }
  }
  if (In.RelrDyn && !In.RelrDyn->Relocs.empty()) {
    addInSec(Config->UseAndroidRelrTags ? DT_ANDROID_RELR : DT_RELR,
             In.RelrDyn);
    addSize(Config->UseAndroidRelrTags ? DT_ANDROID_RELRSZ : DT_RELRSZ,
            In.RelrDyn->getParent());
    addInt(Config->UseAndroidRelrTags ? DT_ANDROID_RELRENT : DT_RELRENT,
           sizeof(Elf_Relr));
  }
  // .rel[a].plt section usually consists of two parts, containing plt and
  // iplt relocations. It is possible to have only iplt relocations in the
  // output. In that case RelaPlt is empty and have zero offset, the same offset
  // as RelaIplt have. And we still want to emit proper dynamic tags for that
  // case, so here we always use RelaPlt as marker for the begining of
  // .rel[a].plt section.
  if (In.RelaPlt->getParent()->Live) {
    addInSec(DT_JMPREL, In.RelaPlt);
    Entries.push_back({DT_PLTRELSZ, addPltRelSz});
    switch (Config->EMachine) {
    case EM_MIPS:
      addInSec(DT_MIPS_PLTGOT, In.GotPlt);
      break;
    case EM_SPARCV9:
      addInSec(DT_PLTGOT, In.Plt);
      break;
    default:
      addInSec(DT_PLTGOT, In.GotPlt);
      break;
    }
    addInt(DT_PLTREL, Config->IsRela ? DT_RELA : DT_REL);
  }

  addInSec(DT_SYMTAB, In.DynSymTab);
  addInt(DT_SYMENT, sizeof(Elf_Sym));
  addInSec(DT_STRTAB, In.DynStrTab);
  addInt(DT_STRSZ, In.DynStrTab->getSize());
  if (!Config->ZText)
    addInt(DT_TEXTREL, 0);
  if (In.GnuHashTab)
    addInSec(DT_GNU_HASH, In.GnuHashTab);
  if (In.HashTab)
    addInSec(DT_HASH, In.HashTab);

  if (Out::PreinitArray) {
    addOutSec(DT_PREINIT_ARRAY, Out::PreinitArray);
    addSize(DT_PREINIT_ARRAYSZ, Out::PreinitArray);
  }
  if (Out::InitArray) {
    addOutSec(DT_INIT_ARRAY, Out::InitArray);
    addSize(DT_INIT_ARRAYSZ, Out::InitArray);
  }
  if (Out::FiniArray) {
    addOutSec(DT_FINI_ARRAY, Out::FiniArray);
    addSize(DT_FINI_ARRAYSZ, Out::FiniArray);
  }

  if (Symbol *B = Symtab->find(Config->Init))
    if (B->isDefined())
      addSym(DT_INIT, B);
  if (Symbol *B = Symtab->find(Config->Fini))
    if (B->isDefined())
      addSym(DT_FINI, B);

  bool HasVerNeed = In.VerNeed->getNeedNum() != 0;
  if (HasVerNeed || In.VerDef)
    addInSec(DT_VERSYM, In.VerSym);
  if (In.VerDef) {
    addInSec(DT_VERDEF, In.VerDef);
    addInt(DT_VERDEFNUM, getVerDefNum());
  }
  if (HasVerNeed) {
    addInSec(DT_VERNEED, In.VerNeed);
    addInt(DT_VERNEEDNUM, In.VerNeed->getNeedNum());
  }

  if (Config->EMachine == EM_MIPS) {
    addInt(DT_MIPS_RLD_VERSION, 1);
    addInt(DT_MIPS_FLAGS, RHF_NOTPOT);
    addInt(DT_MIPS_BASE_ADDRESS, Target->getImageBase());
    addInt(DT_MIPS_SYMTABNO, In.DynSymTab->getNumSymbols());

    add(DT_MIPS_LOCAL_GOTNO, [] { return In.MipsGot->getLocalEntriesNum(); });

    if (const Symbol *B = In.MipsGot->getFirstGlobalEntry())
      addInt(DT_MIPS_GOTSYM, B->DynsymIndex);
    else
      addInt(DT_MIPS_GOTSYM, In.DynSymTab->getNumSymbols());
    addInSec(DT_PLTGOT, In.MipsGot);
    if (In.MipsRldMap) {
      if (!Config->Pie)
        addInSec(DT_MIPS_RLD_MAP, In.MipsRldMap);
      // Store the offset to the .rld_map section
      // relative to the address of the tag.
      addInSecRelative(DT_MIPS_RLD_MAP_REL, In.MipsRldMap);
    }
  }

  // Glink dynamic tag is required by the V2 abi if the plt section isn't empty.
  if (Config->EMachine == EM_PPC64 && !In.Plt->empty()) {
    // The Glink tag points to 32 bytes before the first lazy symbol resolution
    // stub, which starts directly after the header.
    Entries.push_back({DT_PPC64_GLINK, [=] {
                         unsigned Offset = Target->PltHeaderSize - 32;
                         return In.Plt->getVA(0) + Offset;
                       }});
  }

  addInt(DT_NULL, 0);

  getParent()->Link = this->Link;
  this->Size = Entries.size() * this->Entsize;
}

template <class ELFT> void DynamicSection<ELFT>::writeTo(uint8_t *Buf) {
  auto *P = reinterpret_cast<Elf_Dyn *>(Buf);

  for (std::pair<int32_t, std::function<uint64_t()>> &KV : Entries) {
    P->d_tag = KV.first;
    P->d_un.d_val = KV.second();
    ++P;
  }
}

uint64_t DynamicReloc::getOffset() const {
  return InputSec->getVA(OffsetInSec);
}

int64_t DynamicReloc::computeAddend() const {
  if (UseSymVA)
    return Sym->getVA(Addend);
  if (!OutputSec)
    return Addend;
  // See the comment in the DynamicReloc ctor.
  return getMipsPageAddr(OutputSec->Addr) + Addend;
}

uint32_t DynamicReloc::getSymIndex() const {
  if (Sym && !UseSymVA)
    return Sym->DynsymIndex;
  return 0;
}

RelocationBaseSection::RelocationBaseSection(StringRef Name, uint32_t Type,
                                             int32_t DynamicTag,
                                             int32_t SizeDynamicTag)
    : SyntheticSection(SHF_ALLOC, Type, Config->Wordsize, Name),
      DynamicTag(DynamicTag), SizeDynamicTag(SizeDynamicTag) {}

void RelocationBaseSection::addReloc(RelType DynType, InputSectionBase *IS,
                                     uint64_t OffsetInSec, Symbol *Sym) {
  addReloc({DynType, IS, OffsetInSec, false, Sym, 0});
}

void RelocationBaseSection::addReloc(RelType DynType,
                                     InputSectionBase *InputSec,
                                     uint64_t OffsetInSec, Symbol *Sym,
                                     int64_t Addend, RelExpr Expr,
                                     RelType Type) {
  // Write the addends to the relocated address if required. We skip
  // it if the written value would be zero.
  if (Config->WriteAddends && (Expr != R_ADDEND || Addend != 0))
    InputSec->Relocations.push_back({Expr, Type, OffsetInSec, Addend, Sym});
  addReloc({DynType, InputSec, OffsetInSec, Expr != R_ADDEND, Sym, Addend});
}

void RelocationBaseSection::addReloc(const DynamicReloc &Reloc) {
  if (Reloc.Type == Target->RelativeRel)
    ++NumRelativeRelocs;
  Relocs.push_back(Reloc);
}

void RelocationBaseSection::finalizeContents() {
  // When linking glibc statically, .rel{,a}.plt contains R_*_IRELATIVE
  // relocations due to IFUNC (e.g. strcpy). sh_link will be set to 0 in that
  // case.
  if (In.DynSymTab && In.DynSymTab->getParent())
    getParent()->Link = In.DynSymTab->getParent()->SectionIndex;
  else
    getParent()->Link = 0;

  if (In.RelaPlt == this)
    getParent()->Info = In.GotPlt->getParent()->SectionIndex;
  if (In.RelaIplt == this)
    getParent()->Info = In.IgotPlt->getParent()->SectionIndex;
}

RelrBaseSection::RelrBaseSection()
    : SyntheticSection(SHF_ALLOC,
                       Config->UseAndroidRelrTags ? SHT_ANDROID_RELR : SHT_RELR,
                       Config->Wordsize, ".relr.dyn") {}

template <class ELFT>
static void encodeDynamicReloc(typename ELFT::Rela *P,
                               const DynamicReloc &Rel) {
  if (Config->IsRela)
    P->r_addend = Rel.computeAddend();
  P->r_offset = Rel.getOffset();
  P->setSymbolAndType(Rel.getSymIndex(), Rel.Type, Config->IsMips64EL);
}

template <class ELFT>
RelocationSection<ELFT>::RelocationSection(StringRef Name, bool Sort)
    : RelocationBaseSection(Name, Config->IsRela ? SHT_RELA : SHT_REL,
                            Config->IsRela ? DT_RELA : DT_REL,
                            Config->IsRela ? DT_RELASZ : DT_RELSZ),
      Sort(Sort) {
  this->Entsize = Config->IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
}

static bool compRelocations(const DynamicReloc &A, const DynamicReloc &B) {
  bool AIsRel = A.Type == Target->RelativeRel;
  bool BIsRel = B.Type == Target->RelativeRel;
  if (AIsRel != BIsRel)
    return AIsRel;
  return A.getSymIndex() < B.getSymIndex();
}

template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *Buf) {
  if (Sort)
    std::stable_sort(Relocs.begin(), Relocs.end(), compRelocations);

  for (const DynamicReloc &Rel : Relocs) {
    encodeDynamicReloc<ELFT>(reinterpret_cast<Elf_Rela *>(Buf), Rel);
    Buf += Config->IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
  }
}

template <class ELFT>
AndroidPackedRelocationSection<ELFT>::AndroidPackedRelocationSection(
    StringRef Name)
    : RelocationBaseSection(
          Name, Config->IsRela ? SHT_ANDROID_RELA : SHT_ANDROID_REL,
          Config->IsRela ? DT_ANDROID_RELA : DT_ANDROID_REL,
          Config->IsRela ? DT_ANDROID_RELASZ : DT_ANDROID_RELSZ) {
  this->Entsize = 1;
}

template <class ELFT>
bool AndroidPackedRelocationSection<ELFT>::updateAllocSize() {
  // This function computes the contents of an Android-format packed relocation
  // section.
  //
  // This format compresses relocations by using relocation groups to factor out
  // fields that are common between relocations and storing deltas from previous
  // relocations in SLEB128 format (which has a short representation for small
  // numbers). A good example of a relocation type with common fields is
  // R_*_RELATIVE, which is normally used to represent function pointers in
  // vtables. In the REL format, each relative relocation has the same r_info
  // field, and is only different from other relative relocations in terms of
  // the r_offset field. By sorting relocations by offset, grouping them by
  // r_info and representing each relocation with only the delta from the
  // previous offset, each 8-byte relocation can be compressed to as little as 1
  // byte (or less with run-length encoding). This relocation packer was able to
  // reduce the size of the relocation section in an Android Chromium DSO from
  // 2,911,184 bytes to 174,693 bytes, or 6% of the original size.
  //
  // A relocation section consists of a header containing the literal bytes
  // 'APS2' followed by a sequence of SLEB128-encoded integers. The first two
  // elements are the total number of relocations in the section and an initial
  // r_offset value. The remaining elements define a sequence of relocation
  // groups. Each relocation group starts with a header consisting of the
  // following elements:
  //
  // - the number of relocations in the relocation group
  // - flags for the relocation group
  // - (if RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG is set) the r_offset delta
  //   for each relocation in the group.
  // - (if RELOCATION_GROUPED_BY_INFO_FLAG is set) the value of the r_info
  //   field for each relocation in the group.
  // - (if RELOCATION_GROUP_HAS_ADDEND_FLAG and
  //   RELOCATION_GROUPED_BY_ADDEND_FLAG are set) the r_addend delta for
  //   each relocation in the group.
  //
  // Following the relocation group header are descriptions of each of the
  // relocations in the group. They consist of the following elements:
  //
  // - (if RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG is not set) the r_offset
  //   delta for this relocation.
  // - (if RELOCATION_GROUPED_BY_INFO_FLAG is not set) the value of the r_info
  //   field for this relocation.
  // - (if RELOCATION_GROUP_HAS_ADDEND_FLAG is set and
  //   RELOCATION_GROUPED_BY_ADDEND_FLAG is not set) the r_addend delta for
  //   this relocation.

  size_t OldSize = RelocData.size();

  RelocData = {'A', 'P', 'S', '2'};
  raw_svector_ostream OS(RelocData);
  auto Add = [&](int64_t V) { encodeSLEB128(V, OS); };

  // The format header includes the number of relocations and the initial
  // offset (we set this to zero because the first relocation group will
  // perform the initial adjustment).
  Add(Relocs.size());
  Add(0);

  std::vector<Elf_Rela> Relatives, NonRelatives;

  for (const DynamicReloc &Rel : Relocs) {
    Elf_Rela R;
    encodeDynamicReloc<ELFT>(&R, Rel);

    if (R.getType(Config->IsMips64EL) == Target->RelativeRel)
      Relatives.push_back(R);
    else
      NonRelatives.push_back(R);
  }

  llvm::sort(Relatives, [](const Elf_Rel &A, const Elf_Rel &B) {
    return A.r_offset < B.r_offset;
  });

  // Try to find groups of relative relocations which are spaced one word
  // apart from one another. These generally correspond to vtable entries. The
  // format allows these groups to be encoded using a sort of run-length
  // encoding, but each group will cost 7 bytes in addition to the offset from
  // the previous group, so it is only profitable to do this for groups of
  // size 8 or larger.
  std::vector<Elf_Rela> UngroupedRelatives;
  std::vector<std::vector<Elf_Rela>> RelativeGroups;
  for (auto I = Relatives.begin(), E = Relatives.end(); I != E;) {
    std::vector<Elf_Rela> Group;
    do {
      Group.push_back(*I++);
    } while (I != E && (I - 1)->r_offset + Config->Wordsize == I->r_offset);

    if (Group.size() < 8)
      UngroupedRelatives.insert(UngroupedRelatives.end(), Group.begin(),
                                Group.end());
    else
      RelativeGroups.emplace_back(std::move(Group));
  }

  unsigned HasAddendIfRela =
      Config->IsRela ? RELOCATION_GROUP_HAS_ADDEND_FLAG : 0;

  uint64_t Offset = 0;
  uint64_t Addend = 0;

  // Emit the run-length encoding for the groups of adjacent relative
  // relocations. Each group is represented using two groups in the packed
  // format. The first is used to set the current offset to the start of the
  // group (and also encodes the first relocation), and the second encodes the
  // remaining relocations.
  for (std::vector<Elf_Rela> &G : RelativeGroups) {
    // The first relocation in the group.
    Add(1);
    Add(RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG |
        RELOCATION_GROUPED_BY_INFO_FLAG | HasAddendIfRela);
    Add(G[0].r_offset - Offset);
    Add(Target->RelativeRel);
    if (Config->IsRela) {
      Add(G[0].r_addend - Addend);
      Addend = G[0].r_addend;
    }

    // The remaining relocations.
    Add(G.size() - 1);
    Add(RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG |
        RELOCATION_GROUPED_BY_INFO_FLAG | HasAddendIfRela);
    Add(Config->Wordsize);
    Add(Target->RelativeRel);
    if (Config->IsRela) {
      for (auto I = G.begin() + 1, E = G.end(); I != E; ++I) {
        Add(I->r_addend - Addend);
        Addend = I->r_addend;
      }
    }

    Offset = G.back().r_offset;
  }

  // Now the ungrouped relatives.
  if (!UngroupedRelatives.empty()) {
    Add(UngroupedRelatives.size());
    Add(RELOCATION_GROUPED_BY_INFO_FLAG | HasAddendIfRela);
    Add(Target->RelativeRel);
    for (Elf_Rela &R : UngroupedRelatives) {
      Add(R.r_offset - Offset);
      Offset = R.r_offset;
      if (Config->IsRela) {
        Add(R.r_addend - Addend);
        Addend = R.r_addend;
      }
    }
  }

  // Finally the non-relative relocations.
  llvm::sort(NonRelatives, [](const Elf_Rela &A, const Elf_Rela &B) {
    return A.r_offset < B.r_offset;
  });
  if (!NonRelatives.empty()) {
    Add(NonRelatives.size());
    Add(HasAddendIfRela);
    for (Elf_Rela &R : NonRelatives) {
      Add(R.r_offset - Offset);
      Offset = R.r_offset;
      Add(R.r_info);
      if (Config->IsRela) {
        Add(R.r_addend - Addend);
        Addend = R.r_addend;
      }
    }
  }

  // Don't allow the section to shrink; otherwise the size of the section can
  // oscillate infinitely.
  if (RelocData.size() < OldSize)
    RelocData.append(OldSize - RelocData.size(), 0);

  // Returns whether the section size changed. We need to keep recomputing both
  // section layout and the contents of this section until the size converges
  // because changing this section's size can affect section layout, which in
  // turn can affect the sizes of the LEB-encoded integers stored in this
  // section.
  return RelocData.size() != OldSize;
}

template <class ELFT> RelrSection<ELFT>::RelrSection() {
  this->Entsize = Config->Wordsize;
}

template <class ELFT> bool RelrSection<ELFT>::updateAllocSize() {
  // This function computes the contents of an SHT_RELR packed relocation
  // section.
  //
  // Proposal for adding SHT_RELR sections to generic-abi is here:
  //   https://groups.google.com/forum/#!topic/generic-abi/bX460iggiKg
  //
  // The encoded sequence of Elf64_Relr entries in a SHT_RELR section looks
  // like [ AAAAAAAA BBBBBBB1 BBBBBBB1 ... AAAAAAAA BBBBBB1 ... ]
  //
  // i.e. start with an address, followed by any number of bitmaps. The address
  // entry encodes 1 relocation. The subsequent bitmap entries encode up to 63
  // relocations each, at subsequent offsets following the last address entry.
  //
  // The bitmap entries must have 1 in the least significant bit. The assumption
  // here is that an address cannot have 1 in lsb. Odd addresses are not
  // supported.
  //
  // Excluding the least significant bit in the bitmap, each non-zero bit in
  // the bitmap represents a relocation to be applied to a corresponding machine
  // word that follows the base address word. The second least significant bit
  // represents the machine word immediately following the initial address, and
  // each bit that follows represents the next word, in linear order. As such,
  // a single bitmap can encode up to 31 relocations in a 32-bit object, and
  // 63 relocations in a 64-bit object.
  //
  // This encoding has a couple of interesting properties:
  // 1. Looking at any entry, it is clear whether it's an address or a bitmap:
  //    even means address, odd means bitmap.
  // 2. Just a simple list of addresses is a valid encoding.

  size_t OldSize = RelrRelocs.size();
  RelrRelocs.clear();

  // Same as Config->Wordsize but faster because this is a compile-time
  // constant.
  const size_t Wordsize = sizeof(typename ELFT::uint);

  // Number of bits to use for the relocation offsets bitmap.
  // Must be either 63 or 31.
  const size_t NBits = Wordsize * 8 - 1;

  // Get offsets for all relative relocations and sort them.
  std::vector<uint64_t> Offsets;
  for (const RelativeReloc &Rel : Relocs)
    Offsets.push_back(Rel.getOffset());
  llvm::sort(Offsets);

  // For each leading relocation, find following ones that can be folded
  // as a bitmap and fold them.
  for (size_t I = 0, E = Offsets.size(); I < E;) {
    // Add a leading relocation.
    RelrRelocs.push_back(Elf_Relr(Offsets[I]));
    uint64_t Base = Offsets[I] + Wordsize;
    ++I;

    // Find foldable relocations to construct bitmaps.
    while (I < E) {
      uint64_t Bitmap = 0;

      while (I < E) {
        uint64_t Delta = Offsets[I] - Base;

        // If it is too far, it cannot be folded.
        if (Delta >= NBits * Wordsize)
          break;

        // If it is not a multiple of wordsize away, it cannot be folded.
        if (Delta % Wordsize)
          break;

        // Fold it.
        Bitmap |= 1ULL << (Delta / Wordsize);
        ++I;
      }

      if (!Bitmap)
        break;

      RelrRelocs.push_back(Elf_Relr((Bitmap << 1) | 1));
      Base += NBits * Wordsize;
    }
  }

  return RelrRelocs.size() != OldSize;
}

SymbolTableBaseSection::SymbolTableBaseSection(StringTableSection &StrTabSec)
    : SyntheticSection(StrTabSec.isDynamic() ? (uint64_t)SHF_ALLOC : 0,
                       StrTabSec.isDynamic() ? SHT_DYNSYM : SHT_SYMTAB,
                       Config->Wordsize,
                       StrTabSec.isDynamic() ? ".dynsym" : ".symtab"),
      StrTabSec(StrTabSec) {}

// Orders symbols according to their positions in the GOT,
// in compliance with MIPS ABI rules.
// See "Global Offset Table" in Chapter 5 in the following document
// for detailed description:
// ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
static bool sortMipsSymbols(const SymbolTableEntry &L,
                            const SymbolTableEntry &R) {
  // Sort entries related to non-local preemptible symbols by GOT indexes.
  // All other entries go to the beginning of a dynsym in arbitrary order.
  if (L.Sym->isInGot() && R.Sym->isInGot())
    return L.Sym->GotIndex < R.Sym->GotIndex;
  if (!L.Sym->isInGot() && !R.Sym->isInGot())
    return false;
  return !L.Sym->isInGot();
}

void SymbolTableBaseSection::finalizeContents() {
  if (OutputSection *Sec = StrTabSec.getParent())
    getParent()->Link = Sec->SectionIndex;

  if (this->Type != SHT_DYNSYM) {
    sortSymTabSymbols();
    return;
  }

  // If it is a .dynsym, there should be no local symbols, but we need
  // to do a few things for the dynamic linker.

  // Section's Info field has the index of the first non-local symbol.
  // Because the first symbol entry is a null entry, 1 is the first.
  getParent()->Info = 1;

  if (In.GnuHashTab) {
    // NB: It also sorts Symbols to meet the GNU hash table requirements.
    In.GnuHashTab->addSymbols(Symbols);
  } else if (Config->EMachine == EM_MIPS) {
    std::stable_sort(Symbols.begin(), Symbols.end(), sortMipsSymbols);
  }

  size_t I = 0;
  for (const SymbolTableEntry &S : Symbols)
    S.Sym->DynsymIndex = ++I;
}

// The ELF spec requires that all local symbols precede global symbols, so we
// sort symbol entries in this function. (For .dynsym, we don't do that because
// symbols for dynamic linking are inherently all globals.)
//
// Aside from above, we put local symbols in groups starting with the STT_FILE
// symbol. That is convenient for purpose of identifying where are local symbols
// coming from.
void SymbolTableBaseSection::sortSymTabSymbols() {
  // Move all local symbols before global symbols.
  auto E = std::stable_partition(
      Symbols.begin(), Symbols.end(), [](const SymbolTableEntry &S) {
        return S.Sym->isLocal() || S.Sym->computeBinding() == STB_LOCAL;
      });
  size_t NumLocals = E - Symbols.begin();
  getParent()->Info = NumLocals + 1;

  // We want to group the local symbols by file. For that we rebuild the local
  // part of the symbols vector. We do not need to care about the STT_FILE
  // symbols, they are already naturally placed first in each group. That
  // happens because STT_FILE is always the first symbol in the object and hence
  // precede all other local symbols we add for a file.
  MapVector<InputFile *, std::vector<SymbolTableEntry>> Arr;
  for (const SymbolTableEntry &S : llvm::make_range(Symbols.begin(), E))
    Arr[S.Sym->File].push_back(S);

  auto I = Symbols.begin();
  for (std::pair<InputFile *, std::vector<SymbolTableEntry>> &P : Arr)
    for (SymbolTableEntry &Entry : P.second)
      *I++ = Entry;
}

void SymbolTableBaseSection::addSymbol(Symbol *B) {
  // Adding a local symbol to a .dynsym is a bug.
  assert(this->Type != SHT_DYNSYM || !B->isLocal());

  bool HashIt = B->isLocal();
  Symbols.push_back({B, StrTabSec.addString(B->getName(), HashIt)});
}

size_t SymbolTableBaseSection::getSymbolIndex(Symbol *Sym) {
  // Initializes symbol lookup tables lazily. This is used only
  // for -r or -emit-relocs.
  llvm::call_once(OnceFlag, [&] {
    SymbolIndexMap.reserve(Symbols.size());
    size_t I = 0;
    for (const SymbolTableEntry &E : Symbols) {
      if (E.Sym->Type == STT_SECTION)
        SectionIndexMap[E.Sym->getOutputSection()] = ++I;
      else
        SymbolIndexMap[E.Sym] = ++I;
    }
  });

  // Section symbols are mapped based on their output sections
  // to maintain their semantics.
  if (Sym->Type == STT_SECTION)
    return SectionIndexMap.lookup(Sym->getOutputSection());
  return SymbolIndexMap.lookup(Sym);
}

template <class ELFT>
SymbolTableSection<ELFT>::SymbolTableSection(StringTableSection &StrTabSec)
    : SymbolTableBaseSection(StrTabSec) {
  this->Entsize = sizeof(Elf_Sym);
}

static BssSection *getCommonSec(Symbol *Sym) {
  if (!Config->DefineCommon)
    if (auto *D = dyn_cast<Defined>(Sym))
      return dyn_cast_or_null<BssSection>(D->Section);
  return nullptr;
}

static uint32_t getSymSectionIndex(Symbol *Sym) {
  if (getCommonSec(Sym))
    return SHN_COMMON;
  if (!isa<Defined>(Sym) || Sym->NeedsPltAddr)
    return SHN_UNDEF;
  if (const OutputSection *OS = Sym->getOutputSection())
    return OS->SectionIndex >= SHN_LORESERVE ? (uint32_t)SHN_XINDEX
                                             : OS->SectionIndex;
  return SHN_ABS;
}

// Write the internal symbol table contents to the output symbol table.
template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) {
  // The first entry is a null entry as per the ELF spec.
  memset(Buf, 0, sizeof(Elf_Sym));
  Buf += sizeof(Elf_Sym);

  auto *ESym = reinterpret_cast<Elf_Sym *>(Buf);

  for (SymbolTableEntry &Ent : Symbols) {
    Symbol *Sym = Ent.Sym;

    // Set st_info and st_other.
    ESym->st_other = 0;
    if (Sym->isLocal()) {
      ESym->setBindingAndType(STB_LOCAL, Sym->Type);
    } else {
      ESym->setBindingAndType(Sym->computeBinding(), Sym->Type);
      ESym->setVisibility(Sym->Visibility);
    }

    // The 3 most significant bits of st_other are used by OpenPOWER ABI.
    // See getPPC64GlobalEntryToLocalEntryOffset() for more details.
    if (Config->EMachine == EM_PPC64)
      ESym->st_other |= Sym->StOther & 0xe0;

    ESym->st_name = Ent.StrTabOffset;
    ESym->st_shndx = getSymSectionIndex(Ent.Sym);

    // Copy symbol size if it is a defined symbol. st_size is not significant
    // for undefined symbols, so whether copying it or not is up to us if that's
    // the case. We'll leave it as zero because by not setting a value, we can
    // get the exact same outputs for two sets of input files that differ only
    // in undefined symbol size in DSOs.
    if (ESym->st_shndx == SHN_UNDEF)
      ESym->st_size = 0;
    else
      ESym->st_size = Sym->getSize();

    // st_value is usually an address of a symbol, but that has a
    // special meaining for uninstantiated common symbols (this can
    // occur if -r is given).
    if (BssSection *CommonSec = getCommonSec(Ent.Sym))
      ESym->st_value = CommonSec->Alignment;
    else
      ESym->st_value = Sym->getVA();

    ++ESym;
  }

  // On MIPS we need to mark symbol which has a PLT entry and requires
  // pointer equality by STO_MIPS_PLT flag. That is necessary to help
  // dynamic linker distinguish such symbols and MIPS lazy-binding stubs.
  // https://sourceware.org/ml/binutils/2008-07/txt00000.txt
  if (Config->EMachine == EM_MIPS) {
    auto *ESym = reinterpret_cast<Elf_Sym *>(Buf);

    for (SymbolTableEntry &Ent : Symbols) {
      Symbol *Sym = Ent.Sym;
      if (Sym->isInPlt() && Sym->NeedsPltAddr)
        ESym->st_other |= STO_MIPS_PLT;
      if (isMicroMips()) {
        // We already set the less-significant bit for symbols
        // marked by the `STO_MIPS_MICROMIPS` flag and for microMIPS PLT
        // records. That allows us to distinguish such symbols in
        // the `MIPS<ELFT>::relocateOne()` routine. Now we should
        // clear that bit for non-dynamic symbol table, so tools
        // like `objdump` will be able to deal with a correct
        // symbol position.
        if (Sym->isDefined() &&
            ((Sym->StOther & STO_MIPS_MICROMIPS) || Sym->NeedsPltAddr)) {
          if (!StrTabSec.isDynamic())
            ESym->st_value &= ~1;
          ESym->st_other |= STO_MIPS_MICROMIPS;
        }
      }
      if (Config->Relocatable)
        if (auto *D = dyn_cast<Defined>(Sym))
          if (isMipsPIC<ELFT>(D))
            ESym->st_other |= STO_MIPS_PIC;
      ++ESym;
    }
  }
}

SymtabShndxSection::SymtabShndxSection()
    : SyntheticSection(0, SHT_SYMTAB_SHNDX, 4, ".symtab_shndxr") {
  this->Entsize = 4;
}

void SymtabShndxSection::writeTo(uint8_t *Buf) {
  // We write an array of 32 bit values, where each value has 1:1 association
  // with an entry in .symtab. If the corresponding entry contains SHN_XINDEX,
  // we need to write actual index, otherwise, we must write SHN_UNDEF(0).
  Buf += 4; // Ignore .symtab[0] entry.
  for (const SymbolTableEntry &Entry : In.SymTab->getSymbols()) {
    if (getSymSectionIndex(Entry.Sym) == SHN_XINDEX)
      write32(Buf, Entry.Sym->getOutputSection()->SectionIndex);
    Buf += 4;
  }
}

bool SymtabShndxSection::empty() const {
  // SHT_SYMTAB can hold symbols with section indices values up to
  // SHN_LORESERVE. If we need more, we want to use extension SHT_SYMTAB_SHNDX
  // section. Problem is that we reveal the final section indices a bit too
  // late, and we do not know them here. For simplicity, we just always create
  // a .symtab_shndxr section when the amount of output sections is huge.
  size_t Size = 0;
  for (BaseCommand *Base : Script->SectionCommands)
    if (isa<OutputSection>(Base))
      ++Size;
  return Size < SHN_LORESERVE;
}

void SymtabShndxSection::finalizeContents() {
  getParent()->Link = In.SymTab->getParent()->SectionIndex;
}

size_t SymtabShndxSection::getSize() const {
  return In.SymTab->getNumSymbols() * 4;
}

// .hash and .gnu.hash sections contain on-disk hash tables that map
// symbol names to their dynamic symbol table indices. Their purpose
// is to help the dynamic linker resolve symbols quickly. If ELF files
// don't have them, the dynamic linker has to do linear search on all
// dynamic symbols, which makes programs slower. Therefore, a .hash
// section is added to a DSO by default. A .gnu.hash is added if you
// give the -hash-style=gnu or -hash-style=both option.
//
// The Unix semantics of resolving dynamic symbols is somewhat expensive.
// Each ELF file has a list of DSOs that the ELF file depends on and a
// list of dynamic symbols that need to be resolved from any of the
// DSOs. That means resolving all dynamic symbols takes O(m)*O(n)
// where m is the number of DSOs and n is the number of dynamic
// symbols. For modern large programs, both m and n are large.  So
// making each step faster by using hash tables substiantially
// improves time to load programs.
//
// (Note that this is not the only way to design the shared library.
// For instance, the Windows DLL takes a different approach. On
// Windows, each dynamic symbol has a name of DLL from which the symbol
// has to be resolved. That makes the cost of symbol resolution O(n).
// This disables some hacky techniques you can use on Unix such as
// LD_PRELOAD, but this is arguably better semantics than the Unix ones.)
//
// Due to historical reasons, we have two different hash tables, .hash
// and .gnu.hash. They are for the same purpose, and .gnu.hash is a new
// and better version of .hash. .hash is just an on-disk hash table, but
// .gnu.hash has a bloom filter in addition to a hash table to skip
// DSOs very quickly. If you are sure that your dynamic linker knows
// about .gnu.hash, you want to specify -hash-style=gnu. Otherwise, a
// safe bet is to specify -hash-style=both for backward compatibilty.
GnuHashTableSection::GnuHashTableSection()
    : SyntheticSection(SHF_ALLOC, SHT_GNU_HASH, Config->Wordsize, ".gnu.hash") {
}

void GnuHashTableSection::finalizeContents() {
  if (OutputSection *Sec = In.DynSymTab->getParent())
    getParent()->Link = Sec->SectionIndex;

  // Computes bloom filter size in word size. We want to allocate 12
  // bits for each symbol. It must be a power of two.
  if (Symbols.empty()) {
    MaskWords = 1;
  } else {
    uint64_t NumBits = Symbols.size() * 12;
    MaskWords = NextPowerOf2(NumBits / (Config->Wordsize * 8));
  }

  Size = 16;                            // Header
  Size += Config->Wordsize * MaskWords; // Bloom filter
  Size += NBuckets * 4;                 // Hash buckets
  Size += Symbols.size() * 4;           // Hash values
}

void GnuHashTableSection::writeTo(uint8_t *Buf) {
  // The output buffer is not guaranteed to be zero-cleared because we pre-
  // fill executable sections with trap instructions. This is a precaution
  // for that case, which happens only when -no-rosegment is given.
  memset(Buf, 0, Size);

  // Write a header.
  write32(Buf, NBuckets);
  write32(Buf + 4, In.DynSymTab->getNumSymbols() - Symbols.size());
  write32(Buf + 8, MaskWords);
  write32(Buf + 12, Shift2);
  Buf += 16;

  // Write a bloom filter and a hash table.
  writeBloomFilter(Buf);
  Buf += Config->Wordsize * MaskWords;
  writeHashTable(Buf);
}

// This function writes a 2-bit bloom filter. This bloom filter alone
// usually filters out 80% or more of all symbol lookups [1].
// The dynamic linker uses the hash table only when a symbol is not
// filtered out by a bloom filter.
//
// [1] Ulrich Drepper (2011), "How To Write Shared Libraries" (Ver. 4.1.2),
//     p.9, https://www.akkadia.org/drepper/dsohowto.pdf
void GnuHashTableSection::writeBloomFilter(uint8_t *Buf) {
  unsigned C = Config->Is64 ? 64 : 32;
  for (const Entry &Sym : Symbols) {
    // When C = 64, we choose a word with bits [6:...] and set 1 to two bits in
    // the word using bits [0:5] and [26:31].
    size_t I = (Sym.Hash / C) & (MaskWords - 1);
    uint64_t Val = readUint(Buf + I * Config->Wordsize);
    Val |= uint64_t(1) << (Sym.Hash % C);
    Val |= uint64_t(1) << ((Sym.Hash >> Shift2) % C);
    writeUint(Buf + I * Config->Wordsize, Val);
  }
}

void GnuHashTableSection::writeHashTable(uint8_t *Buf) {
  uint32_t *Buckets = reinterpret_cast<uint32_t *>(Buf);
  uint32_t OldBucket = -1;
  uint32_t *Values = Buckets + NBuckets;
  for (auto I = Symbols.begin(), E = Symbols.end(); I != E; ++I) {
    // Write a hash value. It represents a sequence of chains that share the
    // same hash modulo value. The last element of each chain is terminated by
    // LSB 1.
    uint32_t Hash = I->Hash;
    bool IsLastInChain = (I + 1) == E || I->BucketIdx != (I + 1)->BucketIdx;
    Hash = IsLastInChain ? Hash | 1 : Hash & ~1;
    write32(Values++, Hash);

    if (I->BucketIdx == OldBucket)
      continue;
    // Write a hash bucket. Hash buckets contain indices in the following hash
    // value table.
    write32(Buckets + I->BucketIdx, I->Sym->DynsymIndex);
    OldBucket = I->BucketIdx;
  }
}

static uint32_t hashGnu(StringRef Name) {
  uint32_t H = 5381;
  for (uint8_t C : Name)
    H = (H << 5) + H + C;
  return H;
}

// Add symbols to this symbol hash table. Note that this function
// destructively sort a given vector -- which is needed because
// GNU-style hash table places some sorting requirements.
void GnuHashTableSection::addSymbols(std::vector<SymbolTableEntry> &V) {
  // We cannot use 'auto' for Mid because GCC 6.1 cannot deduce
  // its type correctly.
  std::vector<SymbolTableEntry>::iterator Mid =
      std::stable_partition(V.begin(), V.end(), [](const SymbolTableEntry &S) {
        return !S.Sym->isDefined();
      });

  // We chose load factor 4 for the on-disk hash table. For each hash
  // collision, the dynamic linker will compare a uint32_t hash value.
  // Since the integer comparison is quite fast, we believe we can
  // make the load factor even larger. 4 is just a conservative choice.
  //
  // Note that we don't want to create a zero-sized hash table because
  // Android loader as of 2018 doesn't like a .gnu.hash containing such
  // table. If that's the case, we create a hash table with one unused
  // dummy slot.
  NBuckets = std::max<size_t>((V.end() - Mid) / 4, 1);

  if (Mid == V.end())
    return;

  for (SymbolTableEntry &Ent : llvm::make_range(Mid, V.end())) {
    Symbol *B = Ent.Sym;
    uint32_t Hash = hashGnu(B->getName());
    uint32_t BucketIdx = Hash % NBuckets;
    Symbols.push_back({B, Ent.StrTabOffset, Hash, BucketIdx});
  }

  std::stable_sort(
      Symbols.begin(), Symbols.end(),
      [](const Entry &L, const Entry &R) { return L.BucketIdx < R.BucketIdx; });

  V.erase(Mid, V.end());
  for (const Entry &Ent : Symbols)
    V.push_back({Ent.Sym, Ent.StrTabOffset});
}

HashTableSection::HashTableSection()
    : SyntheticSection(SHF_ALLOC, SHT_HASH, 4, ".hash") {
  this->Entsize = 4;
}

void HashTableSection::finalizeContents() {
  if (OutputSection *Sec = In.DynSymTab->getParent())
    getParent()->Link = Sec->SectionIndex;

  unsigned NumEntries = 2;                       // nbucket and nchain.
  NumEntries += In.DynSymTab->getNumSymbols();   // The chain entries.

  // Create as many buckets as there are symbols.
  NumEntries += In.DynSymTab->getNumSymbols();
  this->Size = NumEntries * 4;
}

void HashTableSection::writeTo(uint8_t *Buf) {
  // See comment in GnuHashTableSection::writeTo.
  memset(Buf, 0, Size);

  unsigned NumSymbols = In.DynSymTab->getNumSymbols();

  uint32_t *P = reinterpret_cast<uint32_t *>(Buf);
  write32(P++, NumSymbols); // nbucket
  write32(P++, NumSymbols); // nchain

  uint32_t *Buckets = P;
  uint32_t *Chains = P + NumSymbols;

  for (const SymbolTableEntry &S : In.DynSymTab->getSymbols()) {
    Symbol *Sym = S.Sym;
    StringRef Name = Sym->getName();
    unsigned I = Sym->DynsymIndex;
    uint32_t Hash = hashSysV(Name) % NumSymbols;
    Chains[I] = Buckets[Hash];
    write32(Buckets + Hash, I);
  }
}

// On PowerPC64 the lazy symbol resolvers go into the `global linkage table`
// in the .glink section, rather then the typical .plt section.
PltSection::PltSection(bool IsIplt)
    : SyntheticSection(SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS, 16,
                       Config->EMachine == EM_PPC64 ? ".glink" : ".plt"),
      HeaderSize(!IsIplt || Config->ZRetpolineplt ? Target->PltHeaderSize : 0),
      IsIplt(IsIplt) {
  // The PLT needs to be writable on SPARC as the dynamic linker will
  // modify the instructions in the PLT entries.
  if (Config->EMachine == EM_SPARCV9)
    this->Flags |= SHF_WRITE;
}

void PltSection::writeTo(uint8_t *Buf) {
  // At beginning of PLT or retpoline IPLT, we have code to call the dynamic
  // linker to resolve dynsyms at runtime. Write such code.
  if (HeaderSize)
    Target->writePltHeader(Buf);
  size_t Off = HeaderSize;

  RelocationBaseSection *RelSec = IsIplt ? In.RelaIplt : In.RelaPlt;

  // The IPlt is immediately after the Plt, account for this in RelOff
  size_t PltOff = IsIplt ? In.Plt->getSize() : 0;

  for (size_t I = 0, E = Entries.size(); I != E; ++I) {
    const Symbol *B = Entries[I];
    unsigned RelOff = RelSec->Entsize * I + PltOff;
    uint64_t Got = B->getGotPltVA();
    uint64_t Plt = this->getVA() + Off;
    Target->writePlt(Buf + Off, Got, Plt, B->PltIndex, RelOff);
    Off += Target->PltEntrySize;
  }
}

template <class ELFT> void PltSection::addEntry(Symbol &Sym) {
  Sym.PltIndex = Entries.size();
  Entries.push_back(&Sym);
}

size_t PltSection::getSize() const {
  return HeaderSize + Entries.size() * Target->PltEntrySize;
}

// Some architectures such as additional symbols in the PLT section. For
// example ARM uses mapping symbols to aid disassembly
void PltSection::addSymbols() {
  // The PLT may have symbols defined for the Header, the IPLT has no header
  if (!IsIplt)
    Target->addPltHeaderSymbols(*this);

  size_t Off = HeaderSize;
  for (size_t I = 0; I < Entries.size(); ++I) {
    Target->addPltSymbols(*this, Off);
    Off += Target->PltEntrySize;
  }
}

// The string hash function for .gdb_index.
static uint32_t computeGdbHash(StringRef S) {
  uint32_t H = 0;
  for (uint8_t C : S)
    H = H * 67 + toLower(C) - 113;
  return H;
}

GdbIndexSection::GdbIndexSection()
    : SyntheticSection(0, SHT_PROGBITS, 1, ".gdb_index") {}

// Returns the desired size of an on-disk hash table for a .gdb_index section.
// There's a tradeoff between size and collision rate. We aim 75% utilization.
size_t GdbIndexSection::computeSymtabSize() const {
  return std::max<size_t>(NextPowerOf2(Symbols.size() * 4 / 3), 1024);
}

// Compute the output section size.
void GdbIndexSection::initOutputSize() {
  Size = sizeof(GdbIndexHeader) + computeSymtabSize() * 8;

  for (GdbChunk &Chunk : Chunks)
    Size += Chunk.CompilationUnits.size() * 16 + Chunk.AddressAreas.size() * 20;

  // Add the constant pool size if exists.
  if (!Symbols.empty()) {
    GdbSymbol &Sym = Symbols.back();
    Size += Sym.NameOff + Sym.Name.size() + 1;
  }
}

static std::vector<InputSection *> getDebugInfoSections() {
  std::vector<InputSection *> Ret;
  for (InputSectionBase *S : InputSections)
    if (InputSection *IS = dyn_cast<InputSection>(S))
      if (IS->Name == ".debug_info")
        Ret.push_back(IS);
  return Ret;
}

static std::vector<GdbIndexSection::CuEntry> readCuList(DWARFContext &Dwarf) {
  std::vector<GdbIndexSection::CuEntry> Ret;
  for (std::unique_ptr<DWARFUnit> &Cu : Dwarf.compile_units())
    Ret.push_back({Cu->getOffset(), Cu->getLength() + 4});
  return Ret;
}

static std::vector<GdbIndexSection::AddressEntry>
readAddressAreas(DWARFContext &Dwarf, InputSection *Sec) {
  std::vector<GdbIndexSection::AddressEntry> Ret;

  uint32_t CuIdx = 0;
  for (std::unique_ptr<DWARFUnit> &Cu : Dwarf.compile_units()) {
    Expected<DWARFAddressRangesVector> Ranges = Cu->collectAddressRanges();
    if (!Ranges) {
      error(toString(Sec) + ": " + toString(Ranges.takeError()));
      return {};
    }

    ArrayRef<InputSectionBase *> Sections = Sec->File->getSections();
    for (DWARFAddressRange &R : *Ranges) {
      InputSectionBase *S = Sections[R.SectionIndex];
      if (!S || S == &InputSection::Discarded || !S->Live)
        continue;
      // Range list with zero size has no effect.
      if (R.LowPC == R.HighPC)
        continue;
      auto *IS = cast<InputSection>(S);
      uint64_t Offset = IS->getOffsetInFile();
      Ret.push_back({IS, R.LowPC - Offset, R.HighPC - Offset, CuIdx});
    }
    ++CuIdx;
  }

  return Ret;
}

template <class ELFT>
static std::vector<GdbIndexSection::NameAttrEntry>
readPubNamesAndTypes(const LLDDwarfObj<ELFT> &Obj,
                     const std::vector<GdbIndexSection::CuEntry> &CUs) {
  const DWARFSection &PubNames = Obj.getGnuPubNamesSection();
  const DWARFSection &PubTypes = Obj.getGnuPubTypesSection();

  std::vector<GdbIndexSection::NameAttrEntry> Ret;
  for (const DWARFSection *Pub : {&PubNames, &PubTypes}) {
    DWARFDebugPubTable Table(Obj, *Pub, Config->IsLE, true);
    for (const DWARFDebugPubTable::Set &Set : Table.getData()) {
      // The value written into the constant pool is Kind << 24 | CuIndex. As we
      // don't know how many compilation units precede this object to compute
      // CuIndex, we compute (Kind << 24 | CuIndexInThisObject) instead, and add
      // the number of preceding compilation units later.
      uint32_t I =
          lower_bound(CUs, Set.Offset,
                      [](GdbIndexSection::CuEntry CU, uint32_t Offset) {
                        return CU.CuOffset < Offset;
                      }) -
          CUs.begin();
      for (const DWARFDebugPubTable::Entry &Ent : Set.Entries)
        Ret.push_back({{Ent.Name, computeGdbHash(Ent.Name)},
                       (Ent.Descriptor.toBits() << 24) | I});
    }
  }
  return Ret;
}

// Create a list of symbols from a given list of symbol names and types
// by uniquifying them by name.
static std::vector<GdbIndexSection::GdbSymbol>
createSymbols(ArrayRef<std::vector<GdbIndexSection::NameAttrEntry>> NameAttrs,
              const std::vector<GdbIndexSection::GdbChunk> &Chunks) {
  typedef GdbIndexSection::GdbSymbol GdbSymbol;
  typedef GdbIndexSection::NameAttrEntry NameAttrEntry;

  // For each chunk, compute the number of compilation units preceding it.
  uint32_t CuIdx = 0;
  std::vector<uint32_t> CuIdxs(Chunks.size());
  for (uint32_t I = 0, E = Chunks.size(); I != E; ++I) {
    CuIdxs[I] = CuIdx;
    CuIdx += Chunks[I].CompilationUnits.size();
  }

  // The number of symbols we will handle in this function is of the order
  // of millions for very large executables, so we use multi-threading to
  // speed it up.
  size_t NumShards = 32;
  size_t Concurrency = 1;
  if (ThreadsEnabled)
    Concurrency =
        std::min<size_t>(PowerOf2Floor(hardware_concurrency()), NumShards);

  // A sharded map to uniquify symbols by name.
  std::vector<DenseMap<CachedHashStringRef, size_t>> Map(NumShards);
  size_t Shift = 32 - countTrailingZeros(NumShards);

  // Instantiate GdbSymbols while uniqufying them by name.
  std::vector<std::vector<GdbSymbol>> Symbols(NumShards);
  parallelForEachN(0, Concurrency, [&](size_t ThreadId) {
    uint32_t I = 0;
    for (ArrayRef<NameAttrEntry> Entries : NameAttrs) {
      for (const NameAttrEntry &Ent : Entries) {
        size_t ShardId = Ent.Name.hash() >> Shift;
        if ((ShardId & (Concurrency - 1)) != ThreadId)
          continue;

        uint32_t V = Ent.CuIndexAndAttrs + CuIdxs[I];
        size_t &Idx = Map[ShardId][Ent.Name];
        if (Idx) {
          Symbols[ShardId][Idx - 1].CuVector.push_back(V);
          continue;
        }

        Idx = Symbols[ShardId].size() + 1;
        Symbols[ShardId].push_back({Ent.Name, {V}, 0, 0});
      }
      ++I;
    }
  });

  size_t NumSymbols = 0;
  for (ArrayRef<GdbSymbol> V : Symbols)
    NumSymbols += V.size();

  // The return type is a flattened vector, so we'll copy each vector
  // contents to Ret.
  std::vector<GdbSymbol> Ret;
  Ret.reserve(NumSymbols);
  for (std::vector<GdbSymbol> &Vec : Symbols)
    for (GdbSymbol &Sym : Vec)
      Ret.push_back(std::move(Sym));

  // CU vectors and symbol names are adjacent in the output file.
  // We can compute their offsets in the output file now.
  size_t Off = 0;
  for (GdbSymbol &Sym : Ret) {
    Sym.CuVectorOff = Off;
    Off += (Sym.CuVector.size() + 1) * 4;
  }
  for (GdbSymbol &Sym : Ret) {
    Sym.NameOff = Off;
    Off += Sym.Name.size() + 1;
  }

  return Ret;
}

// Returns a newly-created .gdb_index section.
template <class ELFT> GdbIndexSection *GdbIndexSection::create() {
  std::vector<InputSection *> Sections = getDebugInfoSections();

  // .debug_gnu_pub{names,types} are useless in executables.
  // They are present in input object files solely for creating
  // a .gdb_index. So we can remove them from the output.
  for (InputSectionBase *S : InputSections)
    if (S->Name == ".debug_gnu_pubnames" || S->Name == ".debug_gnu_pubtypes")
      S->Live = false;

  std::vector<GdbChunk> Chunks(Sections.size());
  std::vector<std::vector<NameAttrEntry>> NameAttrs(Sections.size());

  parallelForEachN(0, Sections.size(), [&](size_t I) {
    ObjFile<ELFT> *File = Sections[I]->getFile<ELFT>();
    DWARFContext Dwarf(make_unique<LLDDwarfObj<ELFT>>(File));

    Chunks[I].Sec = Sections[I];
    Chunks[I].CompilationUnits = readCuList(Dwarf);
    Chunks[I].AddressAreas = readAddressAreas(Dwarf, Sections[I]);
    NameAttrs[I] = readPubNamesAndTypes<ELFT>(
        static_cast<const LLDDwarfObj<ELFT> &>(Dwarf.getDWARFObj()),
        Chunks[I].CompilationUnits);
  });

  auto *Ret = make<GdbIndexSection>();
  Ret->Chunks = std::move(Chunks);
  Ret->Symbols = createSymbols(NameAttrs, Ret->Chunks);
  Ret->initOutputSize();
  return Ret;
}

void GdbIndexSection::writeTo(uint8_t *Buf) {
  // Write the header.
  auto *Hdr = reinterpret_cast<GdbIndexHeader *>(Buf);
  uint8_t *Start = Buf;
  Hdr->Version = 7;
  Buf += sizeof(*Hdr);

  // Write the CU list.
  Hdr->CuListOff = Buf - Start;
  for (GdbChunk &Chunk : Chunks) {
    for (CuEntry &Cu : Chunk.CompilationUnits) {
      write64le(Buf, Chunk.Sec->OutSecOff + Cu.CuOffset);
      write64le(Buf + 8, Cu.CuLength);
      Buf += 16;
    }
  }

  // Write the address area.
  Hdr->CuTypesOff = Buf - Start;
  Hdr->AddressAreaOff = Buf - Start;
  uint32_t CuOff = 0;
  for (GdbChunk &Chunk : Chunks) {
    for (AddressEntry &E : Chunk.AddressAreas) {
      uint64_t BaseAddr = E.Section->getVA(0);
      write64le(Buf, BaseAddr + E.LowAddress);
      write64le(Buf + 8, BaseAddr + E.HighAddress);
      write32le(Buf + 16, E.CuIndex + CuOff);
      Buf += 20;
    }
    CuOff += Chunk.CompilationUnits.size();
  }

  // Write the on-disk open-addressing hash table containing symbols.
  Hdr->SymtabOff = Buf - Start;
  size_t SymtabSize = computeSymtabSize();
  uint32_t Mask = SymtabSize - 1;

  for (GdbSymbol &Sym : Symbols) {
    uint32_t H = Sym.Name.hash();
    uint32_t I = H & Mask;
    uint32_t Step = ((H * 17) & Mask) | 1;

    while (read32le(Buf + I * 8))
      I = (I + Step) & Mask;

    write32le(Buf + I * 8, Sym.NameOff);
    write32le(Buf + I * 8 + 4, Sym.CuVectorOff);
  }

  Buf += SymtabSize * 8;

  // Write the string pool.
  Hdr->ConstantPoolOff = Buf - Start;
  parallelForEach(Symbols, [&](GdbSymbol &Sym) {
    memcpy(Buf + Sym.NameOff, Sym.Name.data(), Sym.Name.size());
  });

  // Write the CU vectors.
  for (GdbSymbol &Sym : Symbols) {
    write32le(Buf, Sym.CuVector.size());
    Buf += 4;
    for (uint32_t Val : Sym.CuVector) {
      write32le(Buf, Val);
      Buf += 4;
    }
  }
}

bool GdbIndexSection::empty() const { return Chunks.empty(); }

EhFrameHeader::EhFrameHeader()
    : SyntheticSection(SHF_ALLOC, SHT_PROGBITS, 4, ".eh_frame_hdr") {}

void EhFrameHeader::writeTo(uint8_t *Buf) {
  // Unlike most sections, the EhFrameHeader section is written while writing
  // another section, namely EhFrameSection, which calls the write() function
  // below from its writeTo() function. This is necessary because the contents
  // of EhFrameHeader depend on the relocated contents of EhFrameSection and we
  // don't know which order the sections will be written in.
}

// .eh_frame_hdr contains a binary search table of pointers to FDEs.
// Each entry of the search table consists of two values,
// the starting PC from where FDEs covers, and the FDE's address.
// It is sorted by PC.
void EhFrameHeader::write() {
  uint8_t *Buf = Out::BufferStart + getParent()->Offset + OutSecOff;
  typedef EhFrameSection::FdeData FdeData;

  std::vector<FdeData> Fdes = In.EhFrame->getFdeData();

  Buf[0] = 1;
  Buf[1] = DW_EH_PE_pcrel | DW_EH_PE_sdata4;
  Buf[2] = DW_EH_PE_udata4;
  Buf[3] = DW_EH_PE_datarel | DW_EH_PE_sdata4;
  write32(Buf + 4, In.EhFrame->getParent()->Addr - this->getVA() - 4);
  write32(Buf + 8, Fdes.size());
  Buf += 12;

  for (FdeData &Fde : Fdes) {
    write32(Buf, Fde.PcRel);
    write32(Buf + 4, Fde.FdeVARel);
    Buf += 8;
  }
}

size_t EhFrameHeader::getSize() const {
  // .eh_frame_hdr has a 12 bytes header followed by an array of FDEs.
  return 12 + In.EhFrame->NumFdes * 8;
}

bool EhFrameHeader::empty() const { return In.EhFrame->empty(); }

VersionDefinitionSection::VersionDefinitionSection()
    : SyntheticSection(SHF_ALLOC, SHT_GNU_verdef, sizeof(uint32_t),
                       ".gnu.version_d") {}

static StringRef getFileDefName() {
  if (!Config->SoName.empty())
    return Config->SoName;
  return Config->OutputFile;
}

void VersionDefinitionSection::finalizeContents() {
  FileDefNameOff = In.DynStrTab->addString(getFileDefName());
  for (VersionDefinition &V : Config->VersionDefinitions)
    V.NameOff = In.DynStrTab->addString(V.Name);

  if (OutputSection *Sec = In.DynStrTab->getParent())
    getParent()->Link = Sec->SectionIndex;

  // sh_info should be set to the number of definitions. This fact is missed in
  // documentation, but confirmed by binutils community:
  // https://sourceware.org/ml/binutils/2014-11/msg00355.html
  getParent()->Info = getVerDefNum();
}

void VersionDefinitionSection::writeOne(uint8_t *Buf, uint32_t Index,
                                        StringRef Name, size_t NameOff) {
  uint16_t Flags = Index == 1 ? VER_FLG_BASE : 0;

  // Write a verdef.
  write16(Buf, 1);                  // vd_version
  write16(Buf + 2, Flags);          // vd_flags
  write16(Buf + 4, Index);          // vd_ndx
  write16(Buf + 6, 1);              // vd_cnt
  write32(Buf + 8, hashSysV(Name)); // vd_hash
  write32(Buf + 12, 20);            // vd_aux
  write32(Buf + 16, 28);            // vd_next

  // Write a veraux.
  write32(Buf + 20, NameOff); // vda_name
  write32(Buf + 24, 0);       // vda_next
}

void VersionDefinitionSection::writeTo(uint8_t *Buf) {
  writeOne(Buf, 1, getFileDefName(), FileDefNameOff);

  for (VersionDefinition &V : Config->VersionDefinitions) {
    Buf += EntrySize;
    writeOne(Buf, V.Id, V.Name, V.NameOff);
  }

  // Need to terminate the last version definition.
  write32(Buf + 16, 0); // vd_next
}

size_t VersionDefinitionSection::getSize() const {
  return EntrySize * getVerDefNum();
}

// .gnu.version is a table where each entry is 2 byte long.
VersionTableSection::VersionTableSection()
    : SyntheticSection(SHF_ALLOC, SHT_GNU_versym, sizeof(uint16_t),
                       ".gnu.version") {
  this->Entsize = 2;
}

void VersionTableSection::finalizeContents() {
  // At the moment of june 2016 GNU docs does not mention that sh_link field
  // should be set, but Sun docs do. Also readelf relies on this field.
  getParent()->Link = In.DynSymTab->getParent()->SectionIndex;
}

size_t VersionTableSection::getSize() const {
  return (In.DynSymTab->getSymbols().size() + 1) * 2;
}

void VersionTableSection::writeTo(uint8_t *Buf) {
  Buf += 2;
  for (const SymbolTableEntry &S : In.DynSymTab->getSymbols()) {
    write16(Buf, S.Sym->VersionId);
    Buf += 2;
  }
}

bool VersionTableSection::empty() const {
  return !In.VerDef && In.VerNeed->empty();
}

VersionNeedBaseSection::VersionNeedBaseSection()
    : SyntheticSection(SHF_ALLOC, SHT_GNU_verneed, sizeof(uint32_t),
                       ".gnu.version_r") {
  // Identifiers in verneed section start at 2 because 0 and 1 are reserved
  // for VER_NDX_LOCAL and VER_NDX_GLOBAL.
  // First identifiers are reserved by verdef section if it exist.
  NextIndex = getVerDefNum() + 1;
}

template <class ELFT> void VersionNeedSection<ELFT>::addSymbol(Symbol *SS) {
  auto &File = cast<SharedFile<ELFT>>(*SS->File);
  if (SS->VerdefIndex == VER_NDX_GLOBAL) {
    SS->VersionId = VER_NDX_GLOBAL;
    return;
  }

  // If we don't already know that we need an Elf_Verneed for this DSO, prepare
  // to create one by adding it to our needed list and creating a dynstr entry
  // for the soname.
  if (File.VerdefMap.empty())
    Needed.push_back({&File, In.DynStrTab->addString(File.SoName)});
  const typename ELFT::Verdef *Ver = File.Verdefs[SS->VerdefIndex];
  typename SharedFile<ELFT>::NeededVer &NV = File.VerdefMap[Ver];

  // If we don't already know that we need an Elf_Vernaux for this Elf_Verdef,
  // prepare to create one by allocating a version identifier and creating a
  // dynstr entry for the version name.
  if (NV.Index == 0) {
    NV.StrTab = In.DynStrTab->addString(File.getStringTable().data() +
                                        Ver->getAux()->vda_name);
    NV.Index = NextIndex++;
  }
  SS->VersionId = NV.Index;
}

template <class ELFT> void VersionNeedSection<ELFT>::writeTo(uint8_t *Buf) {
  // The Elf_Verneeds need to appear first, followed by the Elf_Vernauxs.
  auto *Verneed = reinterpret_cast<Elf_Verneed *>(Buf);
  auto *Vernaux = reinterpret_cast<Elf_Vernaux *>(Verneed + Needed.size());

  for (std::pair<SharedFile<ELFT> *, size_t> &P : Needed) {
    // Create an Elf_Verneed for this DSO.
    Verneed->vn_version = 1;
    Verneed->vn_cnt = P.first->VerdefMap.size();
    Verneed->vn_file = P.second;
    Verneed->vn_aux =
        reinterpret_cast<char *>(Vernaux) - reinterpret_cast<char *>(Verneed);
    Verneed->vn_next = sizeof(Elf_Verneed);
    ++Verneed;

    // Create the Elf_Vernauxs for this Elf_Verneed. The loop iterates over
    // VerdefMap, which will only contain references to needed version
    // definitions. Each Elf_Vernaux is based on the information contained in
    // the Elf_Verdef in the source DSO. This loop iterates over a std::map of
    // pointers, but is deterministic because the pointers refer to Elf_Verdef
    // data structures within a single input file.
    for (auto &NV : P.first->VerdefMap) {
      Vernaux->vna_hash = NV.first->vd_hash;
      Vernaux->vna_flags = 0;
      Vernaux->vna_other = NV.second.Index;
      Vernaux->vna_name = NV.second.StrTab;
      Vernaux->vna_next = sizeof(Elf_Vernaux);
      ++Vernaux;
    }

    Vernaux[-1].vna_next = 0;
  }
  Verneed[-1].vn_next = 0;
}

template <class ELFT> void VersionNeedSection<ELFT>::finalizeContents() {
  if (OutputSection *Sec = In.DynStrTab->getParent())
    getParent()->Link = Sec->SectionIndex;
  getParent()->Info = Needed.size();
}

template <class ELFT> size_t VersionNeedSection<ELFT>::getSize() const {
  unsigned Size = Needed.size() * sizeof(Elf_Verneed);
  for (const std::pair<SharedFile<ELFT> *, size_t> &P : Needed)
    Size += P.first->VerdefMap.size() * sizeof(Elf_Vernaux);
  return Size;
}

template <class ELFT> bool VersionNeedSection<ELFT>::empty() const {
  return getNeedNum() == 0;
}

void MergeSyntheticSection::addSection(MergeInputSection *MS) {
  MS->Parent = this;
  Sections.push_back(MS);
}

MergeTailSection::MergeTailSection(StringRef Name, uint32_t Type,
                                   uint64_t Flags, uint32_t Alignment)
    : MergeSyntheticSection(Name, Type, Flags, Alignment),
      Builder(StringTableBuilder::RAW, Alignment) {}

size_t MergeTailSection::getSize() const { return Builder.getSize(); }

void MergeTailSection::writeTo(uint8_t *Buf) { Builder.write(Buf); }

void MergeTailSection::finalizeContents() {
  // Add all string pieces to the string table builder to create section
  // contents.
  for (MergeInputSection *Sec : Sections)
    for (size_t I = 0, E = Sec->Pieces.size(); I != E; ++I)
      if (Sec->Pieces[I].Live)
        Builder.add(Sec->getData(I));

  // Fix the string table content. After this, the contents will never change.
  Builder.finalize();

  // finalize() fixed tail-optimized strings, so we can now get
  // offsets of strings. Get an offset for each string and save it
  // to a corresponding StringPiece for easy access.
  for (MergeInputSection *Sec : Sections)
    for (size_t I = 0, E = Sec->Pieces.size(); I != E; ++I)
      if (Sec->Pieces[I].Live)
        Sec->Pieces[I].OutputOff = Builder.getOffset(Sec->getData(I));
}

void MergeNoTailSection::writeTo(uint8_t *Buf) {
  for (size_t I = 0; I < NumShards; ++I)
    Shards[I].write(Buf + ShardOffsets[I]);
}

// This function is very hot (i.e. it can take several seconds to finish)
// because sometimes the number of inputs is in an order of magnitude of
// millions. So, we use multi-threading.
//
// For any strings S and T, we know S is not mergeable with T if S's hash
// value is different from T's. If that's the case, we can safely put S and
// T into different string builders without worrying about merge misses.
// We do it in parallel.
void MergeNoTailSection::finalizeContents() {
  // Initializes string table builders.
  for (size_t I = 0; I < NumShards; ++I)
    Shards.emplace_back(StringTableBuilder::RAW, Alignment);

  // Concurrency level. Must be a power of 2 to avoid expensive modulo
  // operations in the following tight loop.
  size_t Concurrency = 1;
  if (ThreadsEnabled)
    Concurrency =
        std::min<size_t>(PowerOf2Floor(hardware_concurrency()), NumShards);

  // Add section pieces to the builders.
  parallelForEachN(0, Concurrency, [&](size_t ThreadId) {
    for (MergeInputSection *Sec : Sections) {
      for (size_t I = 0, E = Sec->Pieces.size(); I != E; ++I) {
        size_t ShardId = getShardId(Sec->Pieces[I].Hash);
        if ((ShardId & (Concurrency - 1)) == ThreadId && Sec->Pieces[I].Live)
          Sec->Pieces[I].OutputOff = Shards[ShardId].add(Sec->getData(I));
      }
    }
  });

  // Compute an in-section offset for each shard.
  size_t Off = 0;
  for (size_t I = 0; I < NumShards; ++I) {
    Shards[I].finalizeInOrder();
    if (Shards[I].getSize() > 0)
      Off = alignTo(Off, Alignment);
    ShardOffsets[I] = Off;
    Off += Shards[I].getSize();
  }
  Size = Off;

  // So far, section pieces have offsets from beginning of shards, but
  // we want offsets from beginning of the whole section. Fix them.
  parallelForEach(Sections, [&](MergeInputSection *Sec) {
    for (size_t I = 0, E = Sec->Pieces.size(); I != E; ++I)
      if (Sec->Pieces[I].Live)
        Sec->Pieces[I].OutputOff +=
            ShardOffsets[getShardId(Sec->Pieces[I].Hash)];
  });
}

static MergeSyntheticSection *createMergeSynthetic(StringRef Name,
                                                   uint32_t Type,
                                                   uint64_t Flags,
                                                   uint32_t Alignment) {
  bool ShouldTailMerge = (Flags & SHF_STRINGS) && Config->Optimize >= 2;
  if (ShouldTailMerge)
    return make<MergeTailSection>(Name, Type, Flags, Alignment);
  return make<MergeNoTailSection>(Name, Type, Flags, Alignment);
}

template <class ELFT> void elf::splitSections() {
  // splitIntoPieces needs to be called on each MergeInputSection
  // before calling finalizeContents().
  parallelForEach(InputSections, [](InputSectionBase *Sec) {
    if (auto *S = dyn_cast<MergeInputSection>(Sec))
      S->splitIntoPieces();
    else if (auto *Eh = dyn_cast<EhInputSection>(Sec))
      Eh->split<ELFT>();
  });
}

// This function scans over the inputsections to create mergeable
// synthetic sections.
//
// It removes MergeInputSections from the input section array and adds
// new synthetic sections at the location of the first input section
// that it replaces. It then finalizes each synthetic section in order
// to compute an output offset for each piece of each input section.
void elf::mergeSections() {
  std::vector<MergeSyntheticSection *> MergeSections;
  for (InputSectionBase *&S : InputSections) {
    MergeInputSection *MS = dyn_cast<MergeInputSection>(S);
    if (!MS)
      continue;

    // We do not want to handle sections that are not alive, so just remove
    // them instead of trying to merge.
    if (!MS->Live) {
      S = nullptr;
      continue;
    }

    StringRef OutsecName = getOutputSectionName(MS);

    auto I = llvm::find_if(MergeSections, [=](MergeSyntheticSection *Sec) {
      // While we could create a single synthetic section for two different
      // values of Entsize, it is better to take Entsize into consideration.
      //
      // With a single synthetic section no two pieces with different Entsize
      // could be equal, so we may as well have two sections.
      //
      // Using Entsize in here also allows us to propagate it to the synthetic
      // section.
      return Sec->Name == OutsecName && Sec->Flags == MS->Flags &&
             Sec->Entsize == MS->Entsize && Sec->Alignment == MS->Alignment;
    });
    if (I == MergeSections.end()) {
      MergeSyntheticSection *Syn =
          createMergeSynthetic(OutsecName, MS->Type, MS->Flags, MS->Alignment);
      MergeSections.push_back(Syn);
      I = std::prev(MergeSections.end());
      S = Syn;
      Syn->Entsize = MS->Entsize;
    } else {
      S = nullptr;
    }
    (*I)->addSection(MS);
  }
  for (auto *MS : MergeSections)
    MS->finalizeContents();

  std::vector<InputSectionBase *> &V = InputSections;
  V.erase(std::remove(V.begin(), V.end(), nullptr), V.end());
}

MipsRldMapSection::MipsRldMapSection()
    : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS, Config->Wordsize,
                       ".rld_map") {}

ARMExidxSentinelSection::ARMExidxSentinelSection()
    : SyntheticSection(SHF_ALLOC | SHF_LINK_ORDER, SHT_ARM_EXIDX,
                       Config->Wordsize, ".ARM.exidx") {}

// Write a terminating sentinel entry to the end of the .ARM.exidx table.
// This section will have been sorted last in the .ARM.exidx table.
// This table entry will have the form:
// | PREL31 upper bound of code that has exception tables | EXIDX_CANTUNWIND |
// The sentinel must have the PREL31 value of an address higher than any
// address described by any other table entry.
void ARMExidxSentinelSection::writeTo(uint8_t *Buf) {
  assert(Highest);
  uint64_t S = Highest->getVA(Highest->getSize());
  uint64_t P = getVA();
  Target->relocateOne(Buf, R_ARM_PREL31, S - P);
  write32le(Buf + 4, 1);
}

// The sentinel has to be removed if there are no other .ARM.exidx entries.
bool ARMExidxSentinelSection::empty() const {
  for (InputSection *IS : getInputSections(getParent()))
    if (!isa<ARMExidxSentinelSection>(IS))
      return false;
  return true;
}

bool ARMExidxSentinelSection::classof(const SectionBase *D) {
  return D->kind() == InputSectionBase::Synthetic && D->Type == SHT_ARM_EXIDX;
}

ThunkSection::ThunkSection(OutputSection *OS, uint64_t Off)
    : SyntheticSection(SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS,
                       Config->Wordsize, ".text.thunk") {
  this->Parent = OS;
  this->OutSecOff = Off;
}

void ThunkSection::addThunk(Thunk *T) {
  Thunks.push_back(T);
  T->addSymbols(*this);
}

void ThunkSection::writeTo(uint8_t *Buf) {
  for (Thunk *T : Thunks)
    T->writeTo(Buf + T->Offset);
}

InputSection *ThunkSection::getTargetInputSection() const {
  if (Thunks.empty())
    return nullptr;
  const Thunk *T = Thunks.front();
  return T->getTargetInputSection();
}

bool ThunkSection::assignOffsets() {
  uint64_t Off = 0;
  for (Thunk *T : Thunks) {
    Off = alignTo(Off, T->Alignment);
    T->setOffset(Off);
    uint32_t Size = T->size();
    T->getThunkTargetSym()->Size = Size;
    Off += Size;
  }
  bool Changed = Off != Size;
  Size = Off;
  return Changed;
}

// If linking position-dependent code then the table will store the addresses
// directly in the binary so the section has type SHT_PROGBITS. If linking
// position-independent code the section has type SHT_NOBITS since it will be
// allocated and filled in by the dynamic linker.
PPC64LongBranchTargetSection::PPC64LongBranchTargetSection()
    : SyntheticSection(SHF_ALLOC | SHF_WRITE,
                       Config->Pic ? SHT_NOBITS : SHT_PROGBITS, 8,
                       ".branch_lt") {}

void PPC64LongBranchTargetSection::addEntry(Symbol &Sym) {
  assert(Sym.PPC64BranchltIndex == 0xffff);
  Sym.PPC64BranchltIndex = Entries.size();
  Entries.push_back(&Sym);
}

size_t PPC64LongBranchTargetSection::getSize() const {
  return Entries.size() * 8;
}

void PPC64LongBranchTargetSection::writeTo(uint8_t *Buf) {
  assert(Target->GotPltEntrySize == 8);
  // If linking non-pic we have the final addresses of the targets and they get
  // written to the table directly. For pic the dynamic linker will allocate
  // the section and fill it it.
  if (Config->Pic)
    return;

  for (const Symbol *Sym : Entries) {
    assert(Sym->getVA());
    // Need calls to branch to the local entry-point since a long-branch
    // must be a local-call.
    write64(Buf,
            Sym->getVA() + getPPC64GlobalEntryToLocalEntryOffset(Sym->StOther));
    Buf += Target->GotPltEntrySize;
  }
}

bool PPC64LongBranchTargetSection::empty() const {
  // `removeUnusedSyntheticSections()` is called before thunk allocation which
  // is too early to determine if this section will be empty or not. We need
  // Finalized to keep the section alive until after thunk creation. Finalized
  // only gets set to true once `finalizeSections()` is called after thunk
  // creation. Becuase of this, if we don't create any long-branch thunks we end
  // up with an empty .branch_lt section in the binary.
  return Finalized && Entries.empty();
}

InStruct elf::In;

template GdbIndexSection *GdbIndexSection::create<ELF32LE>();
template GdbIndexSection *GdbIndexSection::create<ELF32BE>();
template GdbIndexSection *GdbIndexSection::create<ELF64LE>();
template GdbIndexSection *GdbIndexSection::create<ELF64BE>();

template void elf::splitSections<ELF32LE>();
template void elf::splitSections<ELF32BE>();
template void elf::splitSections<ELF64LE>();
template void elf::splitSections<ELF64BE>();

template void EhFrameSection::addSection<ELF32LE>(InputSectionBase *);
template void EhFrameSection::addSection<ELF32BE>(InputSectionBase *);
template void EhFrameSection::addSection<ELF64LE>(InputSectionBase *);
template void EhFrameSection::addSection<ELF64BE>(InputSectionBase *);

template void PltSection::addEntry<ELF32LE>(Symbol &Sym);
template void PltSection::addEntry<ELF32BE>(Symbol &Sym);
template void PltSection::addEntry<ELF64LE>(Symbol &Sym);
template void PltSection::addEntry<ELF64BE>(Symbol &Sym);

template class elf::MipsAbiFlagsSection<ELF32LE>;
template class elf::MipsAbiFlagsSection<ELF32BE>;
template class elf::MipsAbiFlagsSection<ELF64LE>;
template class elf::MipsAbiFlagsSection<ELF64BE>;

template class elf::MipsOptionsSection<ELF32LE>;
template class elf::MipsOptionsSection<ELF32BE>;
template class elf::MipsOptionsSection<ELF64LE>;
template class elf::MipsOptionsSection<ELF64BE>;

template class elf::MipsReginfoSection<ELF32LE>;
template class elf::MipsReginfoSection<ELF32BE>;
template class elf::MipsReginfoSection<ELF64LE>;
template class elf::MipsReginfoSection<ELF64BE>;

template class elf::DynamicSection<ELF32LE>;
template class elf::DynamicSection<ELF32BE>;
template class elf::DynamicSection<ELF64LE>;
template class elf::DynamicSection<ELF64BE>;

template class elf::RelocationSection<ELF32LE>;
template class elf::RelocationSection<ELF32BE>;
template class elf::RelocationSection<ELF64LE>;
template class elf::RelocationSection<ELF64BE>;

template class elf::AndroidPackedRelocationSection<ELF32LE>;
template class elf::AndroidPackedRelocationSection<ELF32BE>;
template class elf::AndroidPackedRelocationSection<ELF64LE>;
template class elf::AndroidPackedRelocationSection<ELF64BE>;

template class elf::RelrSection<ELF32LE>;
template class elf::RelrSection<ELF32BE>;
template class elf::RelrSection<ELF64LE>;
template class elf::RelrSection<ELF64BE>;

template class elf::SymbolTableSection<ELF32LE>;
template class elf::SymbolTableSection<ELF32BE>;
template class elf::SymbolTableSection<ELF64LE>;
template class elf::SymbolTableSection<ELF64BE>;

template class elf::VersionNeedSection<ELF32LE>;
template class elf::VersionNeedSection<ELF32BE>;
template class elf::VersionNeedSection<ELF64LE>;
template class elf::VersionNeedSection<ELF64BE>;
