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

#include "InputSection.h"
#include "Config.h"
#include "EhFrame.h"
#include "InputFiles.h"
#include "LinkerScript.h"
#include "OutputSections.h"
#include "Relocations.h"
#include "SymbolTable.h"
#include "Symbols.h"
#include "SyntheticSections.h"
#include "Target.h"
#include "Thunks.h"
#include "lld/Common/ErrorHandler.h"
#include "lld/Common/Memory.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Compression.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Threading.h"
#include "llvm/Support/xxhash.h"
#include <algorithm>
#include <mutex>
#include <set>
#include <vector>

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

using namespace lld;
using namespace lld::elf;

std::vector<InputSectionBase *> elf::InputSections;

// Returns a string to construct an error message.
std::string lld::toString(const InputSectionBase *Sec) {
  return (toString(Sec->File) + ":(" + Sec->Name + ")").str();
}

template <class ELFT>
static ArrayRef<uint8_t> getSectionContents(ObjFile<ELFT> &File,
                                            const typename ELFT::Shdr &Hdr) {
  if (Hdr.sh_type == SHT_NOBITS)
    return makeArrayRef<uint8_t>(nullptr, Hdr.sh_size);
  return check(File.getObj().getSectionContents(&Hdr));
}

InputSectionBase::InputSectionBase(InputFile *File, uint64_t Flags,
                                   uint32_t Type, uint64_t Entsize,
                                   uint32_t Link, uint32_t Info,
                                   uint32_t Alignment, ArrayRef<uint8_t> Data,
                                   StringRef Name, Kind SectionKind)
    : SectionBase(SectionKind, Name, Flags, Entsize, Alignment, Type, Info,
                  Link),
      File(File), RawData(Data) {
  // In order to reduce memory allocation, we assume that mergeable
  // sections are smaller than 4 GiB, which is not an unreasonable
  // assumption as of 2017.
  if (SectionKind == SectionBase::Merge && RawData.size() > UINT32_MAX)
    error(toString(this) + ": section too large");

  NumRelocations = 0;
  AreRelocsRela = false;

  // The ELF spec states that a value of 0 means the section has
  // no alignment constraits.
  uint32_t V = std::max<uint64_t>(Alignment, 1);
  if (!isPowerOf2_64(V))
    fatal(toString(this) + ": sh_addralign is not a power of 2");
  this->Alignment = V;

  // In ELF, each section can be compressed by zlib, and if compressed,
  // section name may be mangled by appending "z" (e.g. ".zdebug_info").
  // If that's the case, demangle section name so that we can handle a
  // section as if it weren't compressed.
  if ((Flags & SHF_COMPRESSED) || Name.startswith(".zdebug")) {
    if (!zlib::isAvailable())
      error(toString(File) + ": contains a compressed section, " +
            "but zlib is not available");
    parseCompressedHeader();
  }
}

// Drop SHF_GROUP bit unless we are producing a re-linkable object file.
// SHF_GROUP is a marker that a section belongs to some comdat group.
// That flag doesn't make sense in an executable.
static uint64_t getFlags(uint64_t Flags) {
  Flags &= ~(uint64_t)SHF_INFO_LINK;
  if (!Config->Relocatable)
    Flags &= ~(uint64_t)SHF_GROUP;
  return Flags;
}

// GNU assembler 2.24 and LLVM 4.0.0's MC (the newest release as of
// March 2017) fail to infer section types for sections starting with
// ".init_array." or ".fini_array.". They set SHT_PROGBITS instead of
// SHF_INIT_ARRAY. As a result, the following assembler directive
// creates ".init_array.100" with SHT_PROGBITS, for example.
//
//   .section .init_array.100, "aw"
//
// This function forces SHT_{INIT,FINI}_ARRAY so that we can handle
// incorrect inputs as if they were correct from the beginning.
static uint64_t getType(uint64_t Type, StringRef Name) {
  if (Type == SHT_PROGBITS && Name.startswith(".init_array."))
    return SHT_INIT_ARRAY;
  if (Type == SHT_PROGBITS && Name.startswith(".fini_array."))
    return SHT_FINI_ARRAY;
  return Type;
}

template <class ELFT>
InputSectionBase::InputSectionBase(ObjFile<ELFT> &File,
                                   const typename ELFT::Shdr &Hdr,
                                   StringRef Name, Kind SectionKind)
    : InputSectionBase(&File, getFlags(Hdr.sh_flags),
                       getType(Hdr.sh_type, Name), Hdr.sh_entsize, Hdr.sh_link,
                       Hdr.sh_info, Hdr.sh_addralign,
                       getSectionContents(File, Hdr), Name, SectionKind) {
  // We reject object files having insanely large alignments even though
  // they are allowed by the spec. I think 4GB is a reasonable limitation.
  // We might want to relax this in the future.
  if (Hdr.sh_addralign > UINT32_MAX)
    fatal(toString(&File) + ": section sh_addralign is too large");
}

size_t InputSectionBase::getSize() const {
  if (auto *S = dyn_cast<SyntheticSection>(this))
    return S->getSize();
  if (UncompressedSize >= 0)
    return UncompressedSize;
  return RawData.size();
}

void InputSectionBase::uncompress() const {
  size_t Size = UncompressedSize;
  char *UncompressedBuf;
  {
    static std::mutex Mu;
    std::lock_guard<std::mutex> Lock(Mu);
    UncompressedBuf = BAlloc.Allocate<char>(Size);
  }

  if (Error E = zlib::uncompress(toStringRef(RawData), UncompressedBuf, Size))
    fatal(toString(this) +
          ": uncompress failed: " + llvm::toString(std::move(E)));
  RawData = makeArrayRef((uint8_t *)UncompressedBuf, Size);
  UncompressedSize = -1;
}

uint64_t InputSectionBase::getOffsetInFile() const {
  const uint8_t *FileStart = (const uint8_t *)File->MB.getBufferStart();
  const uint8_t *SecStart = data().begin();
  return SecStart - FileStart;
}

uint64_t SectionBase::getOffset(uint64_t Offset) const {
  switch (kind()) {
  case Output: {
    auto *OS = cast<OutputSection>(this);
    // For output sections we treat offset -1 as the end of the section.
    return Offset == uint64_t(-1) ? OS->Size : Offset;
  }
  case Regular:
  case Synthetic:
    return cast<InputSection>(this)->getOffset(Offset);
  case EHFrame:
    // The file crtbeginT.o has relocations pointing to the start of an empty
    // .eh_frame that is known to be the first in the link. It does that to
    // identify the start of the output .eh_frame.
    return Offset;
  case Merge:
    const MergeInputSection *MS = cast<MergeInputSection>(this);
    if (InputSection *IS = MS->getParent())
      return IS->getOffset(MS->getParentOffset(Offset));
    return MS->getParentOffset(Offset);
  }
  llvm_unreachable("invalid section kind");
}

uint64_t SectionBase::getVA(uint64_t Offset) const {
  const OutputSection *Out = getOutputSection();
  return (Out ? Out->Addr : 0) + getOffset(Offset);
}

OutputSection *SectionBase::getOutputSection() {
  InputSection *Sec;
  if (auto *IS = dyn_cast<InputSection>(this))
    Sec = IS;
  else if (auto *MS = dyn_cast<MergeInputSection>(this))
    Sec = MS->getParent();
  else if (auto *EH = dyn_cast<EhInputSection>(this))
    Sec = EH->getParent();
  else
    return cast<OutputSection>(this);
  return Sec ? Sec->getParent() : nullptr;
}

// When a section is compressed, `RawData` consists with a header followed
// by zlib-compressed data. This function parses a header to initialize
// `UncompressedSize` member and remove the header from `RawData`.
void InputSectionBase::parseCompressedHeader() {
  typedef typename ELF64LE::Chdr Chdr64;
  typedef typename ELF32LE::Chdr Chdr32;

  // Old-style header
  if (Name.startswith(".zdebug")) {
    if (!toStringRef(RawData).startswith("ZLIB")) {
      error(toString(this) + ": corrupted compressed section header");
      return;
    }
    RawData = RawData.slice(4);

    if (RawData.size() < 8) {
      error(toString(this) + ": corrupted compressed section header");
      return;
    }

    UncompressedSize = read64be(RawData.data());
    RawData = RawData.slice(8);

    // Restore the original section name.
    // (e.g. ".zdebug_info" -> ".debug_info")
    Name = Saver.save("." + Name.substr(2));
    return;
  }

  assert(Flags & SHF_COMPRESSED);
  Flags &= ~(uint64_t)SHF_COMPRESSED;

  // New-style 64-bit header
  if (Config->Is64) {
    if (RawData.size() < sizeof(Chdr64)) {
      error(toString(this) + ": corrupted compressed section");
      return;
    }

    auto *Hdr = reinterpret_cast<const Chdr64 *>(RawData.data());
    if (Hdr->ch_type != ELFCOMPRESS_ZLIB) {
      error(toString(this) + ": unsupported compression type");
      return;
    }

    UncompressedSize = Hdr->ch_size;
    RawData = RawData.slice(sizeof(*Hdr));
    return;
  }

  // New-style 32-bit header
  if (RawData.size() < sizeof(Chdr32)) {
    error(toString(this) + ": corrupted compressed section");
    return;
  }

  auto *Hdr = reinterpret_cast<const Chdr32 *>(RawData.data());
  if (Hdr->ch_type != ELFCOMPRESS_ZLIB) {
    error(toString(this) + ": unsupported compression type");
    return;
  }

  UncompressedSize = Hdr->ch_size;
  RawData = RawData.slice(sizeof(*Hdr));
}

InputSection *InputSectionBase::getLinkOrderDep() const {
  assert(Link);
  assert(Flags & SHF_LINK_ORDER);
  return cast<InputSection>(File->getSections()[Link]);
}

// Find a function symbol that encloses a given location.
template <class ELFT>
Defined *InputSectionBase::getEnclosingFunction(uint64_t Offset) {
  for (Symbol *B : File->getSymbols())
    if (Defined *D = dyn_cast<Defined>(B))
      if (D->Section == this && D->Type == STT_FUNC && D->Value <= Offset &&
          Offset < D->Value + D->Size)
        return D;
  return nullptr;
}

// Returns a source location string. Used to construct an error message.
template <class ELFT>
std::string InputSectionBase::getLocation(uint64_t Offset) {
  std::string SecAndOffset = (Name + "+0x" + utohexstr(Offset)).str();

  // We don't have file for synthetic sections.
  if (getFile<ELFT>() == nullptr)
    return (Config->OutputFile + ":(" + SecAndOffset + ")")
        .str();

  // First check if we can get desired values from debugging information.
  if (Optional<DILineInfo> Info = getFile<ELFT>()->getDILineInfo(this, Offset))
    return Info->FileName + ":" + std::to_string(Info->Line) + ":(" +
           SecAndOffset + ")";

  // File->SourceFile contains STT_FILE symbol that contains a
  // source file name. If it's missing, we use an object file name.
  std::string SrcFile = getFile<ELFT>()->SourceFile;
  if (SrcFile.empty())
    SrcFile = toString(File);

  if (Defined *D = getEnclosingFunction<ELFT>(Offset))
    return SrcFile + ":(function " + toString(*D) + ": " + SecAndOffset + ")";

  // If there's no symbol, print out the offset in the section.
  return (SrcFile + ":(" + SecAndOffset + ")");
}

// This function is intended to be used for constructing an error message.
// The returned message looks like this:
//
//   foo.c:42 (/home/alice/possibly/very/long/path/foo.c:42)
//
//  Returns an empty string if there's no way to get line info.
std::string InputSectionBase::getSrcMsg(const Symbol &Sym, uint64_t Offset) {
  return File->getSrcMsg(Sym, *this, Offset);
}

// Returns a filename string along with an optional section name. This
// function is intended to be used for constructing an error
// message. The returned message looks like this:
//
//   path/to/foo.o:(function bar)
//
// or
//
//   path/to/foo.o:(function bar) in archive path/to/bar.a
std::string InputSectionBase::getObjMsg(uint64_t Off) {
  std::string Filename = File->getName();

  std::string Archive;
  if (!File->ArchiveName.empty())
    Archive = " in archive " + File->ArchiveName;

  // Find a symbol that encloses a given location.
  for (Symbol *B : File->getSymbols())
    if (auto *D = dyn_cast<Defined>(B))
      if (D->Section == this && D->Value <= Off && Off < D->Value + D->Size)
        return Filename + ":(" + toString(*D) + ")" + Archive;

  // If there's no symbol, print out the offset in the section.
  return (Filename + ":(" + Name + "+0x" + utohexstr(Off) + ")" + Archive)
      .str();
}

InputSection InputSection::Discarded(nullptr, 0, 0, 0, ArrayRef<uint8_t>(), "");

InputSection::InputSection(InputFile *F, uint64_t Flags, uint32_t Type,
                           uint32_t Alignment, ArrayRef<uint8_t> Data,
                           StringRef Name, Kind K)
    : InputSectionBase(F, Flags, Type,
                       /*Entsize*/ 0, /*Link*/ 0, /*Info*/ 0, Alignment, Data,
                       Name, K) {}

template <class ELFT>
InputSection::InputSection(ObjFile<ELFT> &F, const typename ELFT::Shdr &Header,
                           StringRef Name)
    : InputSectionBase(F, Header, Name, InputSectionBase::Regular) {}

bool InputSection::classof(const SectionBase *S) {
  return S->kind() == SectionBase::Regular ||
         S->kind() == SectionBase::Synthetic;
}

OutputSection *InputSection::getParent() const {
  return cast_or_null<OutputSection>(Parent);
}

// Copy SHT_GROUP section contents. Used only for the -r option.
template <class ELFT> void InputSection::copyShtGroup(uint8_t *Buf) {
  // ELFT::Word is the 32-bit integral type in the target endianness.
  typedef typename ELFT::Word u32;
  ArrayRef<u32> From = getDataAs<u32>();
  auto *To = reinterpret_cast<u32 *>(Buf);

  // The first entry is not a section number but a flag.
  *To++ = From[0];

  // Adjust section numbers because section numbers in an input object
  // files are different in the output.
  ArrayRef<InputSectionBase *> Sections = File->getSections();
  for (uint32_t Idx : From.slice(1))
    *To++ = Sections[Idx]->getOutputSection()->SectionIndex;
}

InputSectionBase *InputSection::getRelocatedSection() const {
  if (!File || (Type != SHT_RELA && Type != SHT_REL))
    return nullptr;
  ArrayRef<InputSectionBase *> Sections = File->getSections();
  return Sections[Info];
}

// This is used for -r and --emit-relocs. We can't use memcpy to copy
// relocations because we need to update symbol table offset and section index
// for each relocation. So we copy relocations one by one.
template <class ELFT, class RelTy>
void InputSection::copyRelocations(uint8_t *Buf, ArrayRef<RelTy> Rels) {
  InputSectionBase *Sec = getRelocatedSection();

  for (const RelTy &Rel : Rels) {
    RelType Type = Rel.getType(Config->IsMips64EL);
    Symbol &Sym = getFile<ELFT>()->getRelocTargetSym(Rel);

    auto *P = reinterpret_cast<typename ELFT::Rela *>(Buf);
    Buf += sizeof(RelTy);

    if (RelTy::IsRela)
      P->r_addend = getAddend<ELFT>(Rel);

    // Output section VA is zero for -r, so r_offset is an offset within the
    // section, but for --emit-relocs it is an virtual address.
    P->r_offset = Sec->getVA(Rel.r_offset);
    P->setSymbolAndType(In.SymTab->getSymbolIndex(&Sym), Type,
                        Config->IsMips64EL);

    if (Sym.Type == STT_SECTION) {
      // We combine multiple section symbols into only one per
      // section. This means we have to update the addend. That is
      // trivial for Elf_Rela, but for Elf_Rel we have to write to the
      // section data. We do that by adding to the Relocation vector.

      // .eh_frame is horribly special and can reference discarded sections. To
      // avoid having to parse and recreate .eh_frame, we just replace any
      // relocation in it pointing to discarded sections with R_*_NONE, which
      // hopefully creates a frame that is ignored at runtime.
      auto *D = dyn_cast<Defined>(&Sym);
      if (!D) {
        error("STT_SECTION symbol should be defined");
        continue;
      }
      SectionBase *Section = D->Section->Repl;
      if (!Section->Live) {
        P->setSymbolAndType(0, 0, false);
        continue;
      }

      int64_t Addend = getAddend<ELFT>(Rel);
      const uint8_t *BufLoc = Sec->data().begin() + Rel.r_offset;
      if (!RelTy::IsRela)
        Addend = Target->getImplicitAddend(BufLoc, Type);

      if (Config->EMachine == EM_MIPS && Config->Relocatable &&
          Target->getRelExpr(Type, Sym, BufLoc) == R_MIPS_GOTREL) {
        // Some MIPS relocations depend on "gp" value. By default,
        // this value has 0x7ff0 offset from a .got section. But
        // relocatable files produced by a complier or a linker
        // might redefine this default value and we must use it
        // for a calculation of the relocation result. When we
        // generate EXE or DSO it's trivial. Generating a relocatable
        // output is more difficult case because the linker does
        // not calculate relocations in this mode and loses
        // individual "gp" values used by each input object file.
        // As a workaround we add the "gp" value to the relocation
        // addend and save it back to the file.
        Addend += Sec->getFile<ELFT>()->MipsGp0;
      }

      if (RelTy::IsRela)
        P->r_addend = Sym.getVA(Addend) - Section->getOutputSection()->Addr;
      else if (Config->Relocatable)
        Sec->Relocations.push_back({R_ABS, Type, Rel.r_offset, Addend, &Sym});
    }
  }
}

// The ARM and AArch64 ABI handle pc-relative relocations to undefined weak
// references specially. The general rule is that the value of the symbol in
// this context is the address of the place P. A further special case is that
// branch relocations to an undefined weak reference resolve to the next
// instruction.
static uint32_t getARMUndefinedRelativeWeakVA(RelType Type, uint32_t A,
                                              uint32_t P) {
  switch (Type) {
  // Unresolved branch relocations to weak references resolve to next
  // instruction, this will be either 2 or 4 bytes on from P.
  case R_ARM_THM_JUMP11:
    return P + 2 + A;
  case R_ARM_CALL:
  case R_ARM_JUMP24:
  case R_ARM_PC24:
  case R_ARM_PLT32:
  case R_ARM_PREL31:
  case R_ARM_THM_JUMP19:
  case R_ARM_THM_JUMP24:
    return P + 4 + A;
  case R_ARM_THM_CALL:
    // We don't want an interworking BLX to ARM
    return P + 5 + A;
  // Unresolved non branch pc-relative relocations
  // R_ARM_TARGET2 which can be resolved relatively is not present as it never
  // targets a weak-reference.
  case R_ARM_MOVW_PREL_NC:
  case R_ARM_MOVT_PREL:
  case R_ARM_REL32:
  case R_ARM_THM_MOVW_PREL_NC:
  case R_ARM_THM_MOVT_PREL:
    return P + A;
  }
  llvm_unreachable("ARM pc-relative relocation expected\n");
}

// The comment above getARMUndefinedRelativeWeakVA applies to this function.
static uint64_t getAArch64UndefinedRelativeWeakVA(uint64_t Type, uint64_t A,
                                                  uint64_t P) {
  switch (Type) {
  // Unresolved branch relocations to weak references resolve to next
  // instruction, this is 4 bytes on from P.
  case R_AARCH64_CALL26:
  case R_AARCH64_CONDBR19:
  case R_AARCH64_JUMP26:
  case R_AARCH64_TSTBR14:
    return P + 4 + A;
  // Unresolved non branch pc-relative relocations
  case R_AARCH64_PREL16:
  case R_AARCH64_PREL32:
  case R_AARCH64_PREL64:
  case R_AARCH64_ADR_PREL_LO21:
  case R_AARCH64_LD_PREL_LO19:
    return P + A;
  }
  llvm_unreachable("AArch64 pc-relative relocation expected\n");
}

// ARM SBREL relocations are of the form S + A - B where B is the static base
// The ARM ABI defines base to be "addressing origin of the output segment
// defining the symbol S". We defined the "addressing origin"/static base to be
// the base of the PT_LOAD segment containing the Sym.
// The procedure call standard only defines a Read Write Position Independent
// RWPI variant so in practice we should expect the static base to be the base
// of the RW segment.
static uint64_t getARMStaticBase(const Symbol &Sym) {
  OutputSection *OS = Sym.getOutputSection();
  if (!OS || !OS->PtLoad || !OS->PtLoad->FirstSec)
    fatal("SBREL relocation to " + Sym.getName() + " without static base");
  return OS->PtLoad->FirstSec->Addr;
}

// For R_RISCV_PC_INDIRECT (R_RISCV_PCREL_LO12_{I,S}), the symbol actually
// points the corresponding R_RISCV_PCREL_HI20 relocation, and the target VA
// is calculated using PCREL_HI20's symbol.
//
// This function returns the R_RISCV_PCREL_HI20 relocation from
// R_RISCV_PCREL_LO12's symbol and addend.
static Relocation *getRISCVPCRelHi20(const Symbol *Sym, uint64_t Addend) {
  const Defined *D = cast<Defined>(Sym);
  InputSection *IS = cast<InputSection>(D->Section);

  if (Addend != 0)
    warn("Non-zero addend in R_RISCV_PCREL_LO12 relocation to " +
         IS->getObjMsg(D->Value) + " is ignored");

  // Relocations are sorted by offset, so we can use std::equal_range to do
  // binary search.
  Relocation R;
  R.Offset = D->Value;
  auto Range =
      std::equal_range(IS->Relocations.begin(), IS->Relocations.end(), R,
                       [](const Relocation &LHS, const Relocation &RHS) {
                         return LHS.Offset < RHS.Offset;
                       });

  for (auto It = Range.first; It != Range.second; ++It)
    if (It->Expr == R_PC)
      return &*It;

  error("R_RISCV_PCREL_LO12 relocation points to " + IS->getObjMsg(D->Value) +
        " without an associated R_RISCV_PCREL_HI20 relocation");
  return nullptr;
}

// A TLS symbol's virtual address is relative to the TLS segment. Add a
// target-specific adjustment to produce a thread-pointer-relative offset.
static int64_t getTlsTpOffset() {
  switch (Config->EMachine) {
  case EM_ARM:
  case EM_AARCH64:
    // Variant 1. The thread pointer points to a TCB with a fixed 2-word size,
    // followed by a variable amount of alignment padding, followed by the TLS
    // segment.
    //
    // NB: While the ARM/AArch64 ABI formally has a 2-word TCB size, lld
    // effectively increases the TCB size to 8 words for Android compatibility.
    // It accomplishes this by increasing the segment's alignment.
    return alignTo(Config->Wordsize * 2, Out::TlsPhdr->p_align);
  case EM_386:
  case EM_X86_64:
    // Variant 2. The TLS segment is located just before the thread pointer.
    return -Out::TlsPhdr->p_memsz;
  case EM_PPC64:
    // The thread pointer points to a fixed offset from the start of the
    // executable's TLS segment. An offset of 0x7000 allows a signed 16-bit
    // offset to reach 0x1000 of TCB/thread-library data and 0xf000 of the
    // program's TLS segment.
    return -0x7000;
  default:
    llvm_unreachable("unhandled Config->EMachine");
  }
}

static uint64_t getRelocTargetVA(const InputFile *File, RelType Type, int64_t A,
                                 uint64_t P, const Symbol &Sym, RelExpr Expr) {
  switch (Expr) {
  case R_ABS:
  case R_RELAX_TLS_LD_TO_LE_ABS:
  case R_RELAX_GOT_PC_NOPIC:
    return Sym.getVA(A);
  case R_ADDEND:
    return A;
  case R_ARM_SBREL:
    return Sym.getVA(A) - getARMStaticBase(Sym);
  case R_GOT:
  case R_RELAX_TLS_GD_TO_IE_ABS:
    return Sym.getGotVA() + A;
  case R_GOTONLY_PC:
    return In.Got->getVA() + A - P;
  case R_GOTPLTONLY_PC:
    return In.GotPlt->getVA() + A - P;
  case R_GOTREL:
    return Sym.getVA(A) - In.Got->getVA();
  case R_GOTPLTREL:
    return Sym.getVA(A) - In.GotPlt->getVA();
  case R_GOTPLT:
  case R_RELAX_TLS_GD_TO_IE_END:
    return Sym.getGotVA() + A - In.GotPlt->getVA();
  case R_TLSLD_GOT_OFF:
  case R_GOT_OFF:
  case R_RELAX_TLS_GD_TO_IE_GOT_OFF:
    return Sym.getGotOffset() + A;
  case R_AARCH64_GOT_PAGE_PC:
  case R_AARCH64_RELAX_TLS_GD_TO_IE_PAGE_PC:
    return getAArch64Page(Sym.getGotVA() + A) - getAArch64Page(P);
  case R_GOT_PC:
  case R_RELAX_TLS_GD_TO_IE:
    return Sym.getGotVA() + A - P;
  case R_HEXAGON_GOT:
    return Sym.getGotVA() - In.GotPlt->getVA();
  case R_MIPS_GOTREL:
    return Sym.getVA(A) - In.MipsGot->getGp(File);
  case R_MIPS_GOT_GP:
    return In.MipsGot->getGp(File) + A;
  case R_MIPS_GOT_GP_PC: {
    // R_MIPS_LO16 expression has R_MIPS_GOT_GP_PC type iif the target
    // is _gp_disp symbol. In that case we should use the following
    // formula for calculation "AHL + GP - P + 4". For details see p. 4-19 at
    // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
    // microMIPS variants of these relocations use slightly different
    // expressions: AHL + GP - P + 3 for %lo() and AHL + GP - P - 1 for %hi()
    // to correctly handle less-sugnificant bit of the microMIPS symbol.
    uint64_t V = In.MipsGot->getGp(File) + A - P;
    if (Type == R_MIPS_LO16 || Type == R_MICROMIPS_LO16)
      V += 4;
    if (Type == R_MICROMIPS_LO16 || Type == R_MICROMIPS_HI16)
      V -= 1;
    return V;
  }
  case R_MIPS_GOT_LOCAL_PAGE:
    // If relocation against MIPS local symbol requires GOT entry, this entry
    // should be initialized by 'page address'. This address is high 16-bits
    // of sum the symbol's value and the addend.
    return In.MipsGot->getVA() + In.MipsGot->getPageEntryOffset(File, Sym, A) -
           In.MipsGot->getGp(File);
  case R_MIPS_GOT_OFF:
  case R_MIPS_GOT_OFF32:
    // In case of MIPS if a GOT relocation has non-zero addend this addend
    // should be applied to the GOT entry content not to the GOT entry offset.
    // That is why we use separate expression type.
    return In.MipsGot->getVA() + In.MipsGot->getSymEntryOffset(File, Sym, A) -
           In.MipsGot->getGp(File);
  case R_MIPS_TLSGD:
    return In.MipsGot->getVA() + In.MipsGot->getGlobalDynOffset(File, Sym) -
           In.MipsGot->getGp(File);
  case R_MIPS_TLSLD:
    return In.MipsGot->getVA() + In.MipsGot->getTlsIndexOffset(File) -
           In.MipsGot->getGp(File);
  case R_AARCH64_PAGE_PC: {
    uint64_t Val = Sym.isUndefWeak() ? P + A : Sym.getVA(A);
    return getAArch64Page(Val) - getAArch64Page(P);
  }
  case R_RISCV_PC_INDIRECT: {
    if (const Relocation *HiRel = getRISCVPCRelHi20(&Sym, A))
      return getRelocTargetVA(File, HiRel->Type, HiRel->Addend, Sym.getVA(),
                              *HiRel->Sym, HiRel->Expr);
    return 0;
  }
  case R_PC: {
    uint64_t Dest;
    if (Sym.isUndefWeak()) {
      // On ARM and AArch64 a branch to an undefined weak resolves to the
      // next instruction, otherwise the place.
      if (Config->EMachine == EM_ARM)
        Dest = getARMUndefinedRelativeWeakVA(Type, A, P);
      else if (Config->EMachine == EM_AARCH64)
        Dest = getAArch64UndefinedRelativeWeakVA(Type, A, P);
      else
        Dest = Sym.getVA(A);
    } else {
      Dest = Sym.getVA(A);
    }
    return Dest - P;
  }
  case R_PLT:
    return Sym.getPltVA() + A;
  case R_PLT_PC:
  case R_PPC_CALL_PLT:
    return Sym.getPltVA() + A - P;
  case R_PPC_CALL: {
    uint64_t SymVA = Sym.getVA(A);
    // If we have an undefined weak symbol, we might get here with a symbol
    // address of zero. That could overflow, but the code must be unreachable,
    // so don't bother doing anything at all.
    if (!SymVA)
      return 0;

    // PPC64 V2 ABI describes two entry points to a function. The global entry
    // point is used for calls where the caller and callee (may) have different
    // TOC base pointers and r2 needs to be modified to hold the TOC base for
    // the callee. For local calls the caller and callee share the same
    // TOC base and so the TOC pointer initialization code should be skipped by
    // branching to the local entry point.
    return SymVA - P + getPPC64GlobalEntryToLocalEntryOffset(Sym.StOther);
  }
  case R_PPC_TOC:
    return getPPC64TocBase() + A;
  case R_RELAX_GOT_PC:
    return Sym.getVA(A) - P;
  case R_RELAX_TLS_GD_TO_LE:
  case R_RELAX_TLS_IE_TO_LE:
  case R_RELAX_TLS_LD_TO_LE:
  case R_TLS:
    // A weak undefined TLS symbol resolves to the base of the TLS
    // block, i.e. gets a value of zero. If we pass --gc-sections to
    // lld and .tbss is not referenced, it gets reclaimed and we don't
    // create a TLS program header. Therefore, we resolve this
    // statically to zero.
    if (Sym.isTls() && Sym.isUndefWeak())
      return 0;
    return Sym.getVA(A) + getTlsTpOffset();
  case R_RELAX_TLS_GD_TO_LE_NEG:
  case R_NEG_TLS:
    return Out::TlsPhdr->p_memsz - Sym.getVA(A);
  case R_SIZE:
    return Sym.getSize() + A;
  case R_TLSDESC:
    return In.Got->getGlobalDynAddr(Sym) + A;
  case R_AARCH64_TLSDESC_PAGE:
    return getAArch64Page(In.Got->getGlobalDynAddr(Sym) + A) -
           getAArch64Page(P);
  case R_TLSGD_GOT:
    return In.Got->getGlobalDynOffset(Sym) + A;
  case R_TLSGD_GOTPLT:
    return In.Got->getVA() + In.Got->getGlobalDynOffset(Sym) + A - In.GotPlt->getVA();
  case R_TLSGD_PC:
    return In.Got->getGlobalDynAddr(Sym) + A - P;
  case R_TLSLD_GOTPLT:
    return In.Got->getVA() + In.Got->getTlsIndexOff() + A - In.GotPlt->getVA();
  case R_TLSLD_GOT:
    return In.Got->getTlsIndexOff() + A;
  case R_TLSLD_PC:
    return In.Got->getTlsIndexVA() + A - P;
  default:
    llvm_unreachable("invalid expression");
  }
}

// This function applies relocations to sections without SHF_ALLOC bit.
// Such sections are never mapped to memory at runtime. Debug sections are
// an example. Relocations in non-alloc sections are much easier to
// handle than in allocated sections because it will never need complex
// treatement such as GOT or PLT (because at runtime no one refers them).
// So, we handle relocations for non-alloc sections directly in this
// function as a performance optimization.
template <class ELFT, class RelTy>
void InputSection::relocateNonAlloc(uint8_t *Buf, ArrayRef<RelTy> Rels) {
  const unsigned Bits = sizeof(typename ELFT::uint) * 8;

  for (const RelTy &Rel : Rels) {
    RelType Type = Rel.getType(Config->IsMips64EL);

    // GCC 8.0 or earlier have a bug that they emit R_386_GOTPC relocations
    // against _GLOBAL_OFFSET_TABLE_ for .debug_info. The bug has been fixed
    // in 2017 (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82630), but we
    // need to keep this bug-compatible code for a while.
    if (Config->EMachine == EM_386 && Type == R_386_GOTPC)
      continue;

    uint64_t Offset = getOffset(Rel.r_offset);
    uint8_t *BufLoc = Buf + Offset;
    int64_t Addend = getAddend<ELFT>(Rel);
    if (!RelTy::IsRela)
      Addend += Target->getImplicitAddend(BufLoc, Type);

    Symbol &Sym = getFile<ELFT>()->getRelocTargetSym(Rel);
    RelExpr Expr = Target->getRelExpr(Type, Sym, BufLoc);
    if (Expr == R_NONE)
      continue;

    if (Expr != R_ABS) {
      std::string Msg = getLocation<ELFT>(Offset) +
                        ": has non-ABS relocation " + toString(Type) +
                        " against symbol '" + toString(Sym) + "'";
      if (Expr != R_PC) {
        error(Msg);
        return;
      }

      // If the control reaches here, we found a PC-relative relocation in a
      // non-ALLOC section. Since non-ALLOC section is not loaded into memory
      // at runtime, the notion of PC-relative doesn't make sense here. So,
      // this is a usage error. However, GNU linkers historically accept such
      // relocations without any errors and relocate them as if they were at
      // address 0. For bug-compatibilty, we accept them with warnings. We
      // know Steel Bank Common Lisp as of 2018 have this bug.
      warn(Msg);
      Target->relocateOne(BufLoc, Type,
                          SignExtend64<Bits>(Sym.getVA(Addend - Offset)));
      continue;
    }

    if (Sym.isTls() && !Out::TlsPhdr)
      Target->relocateOne(BufLoc, Type, 0);
    else
      Target->relocateOne(BufLoc, Type, SignExtend64<Bits>(Sym.getVA(Addend)));
  }
}

// This is used when '-r' is given.
// For REL targets, InputSection::copyRelocations() may store artificial
// relocations aimed to update addends. They are handled in relocateAlloc()
// for allocatable sections, and this function does the same for
// non-allocatable sections, such as sections with debug information.
static void relocateNonAllocForRelocatable(InputSection *Sec, uint8_t *Buf) {
  const unsigned Bits = Config->Is64 ? 64 : 32;

  for (const Relocation &Rel : Sec->Relocations) {
    // InputSection::copyRelocations() adds only R_ABS relocations.
    assert(Rel.Expr == R_ABS);
    uint8_t *BufLoc = Buf + Rel.Offset + Sec->OutSecOff;
    uint64_t TargetVA = SignExtend64(Rel.Sym->getVA(Rel.Addend), Bits);
    Target->relocateOne(BufLoc, Rel.Type, TargetVA);
  }
}

template <class ELFT>
void InputSectionBase::relocate(uint8_t *Buf, uint8_t *BufEnd) {
  if (Flags & SHF_EXECINSTR)
    adjustSplitStackFunctionPrologues<ELFT>(Buf, BufEnd);

  if (Flags & SHF_ALLOC) {
    relocateAlloc(Buf, BufEnd);
    return;
  }

  auto *Sec = cast<InputSection>(this);
  if (Config->Relocatable)
    relocateNonAllocForRelocatable(Sec, Buf);
  else if (Sec->AreRelocsRela)
    Sec->relocateNonAlloc<ELFT>(Buf, Sec->template relas<ELFT>());
  else
    Sec->relocateNonAlloc<ELFT>(Buf, Sec->template rels<ELFT>());
}

void InputSectionBase::relocateAlloc(uint8_t *Buf, uint8_t *BufEnd) {
  assert(Flags & SHF_ALLOC);
  const unsigned Bits = Config->Wordsize * 8;

  for (const Relocation &Rel : Relocations) {
    uint64_t Offset = Rel.Offset;
    if (auto *Sec = dyn_cast<InputSection>(this))
      Offset += Sec->OutSecOff;
    uint8_t *BufLoc = Buf + Offset;
    RelType Type = Rel.Type;

    uint64_t AddrLoc = getOutputSection()->Addr + Offset;
    RelExpr Expr = Rel.Expr;
    uint64_t TargetVA = SignExtend64(
        getRelocTargetVA(File, Type, Rel.Addend, AddrLoc, *Rel.Sym, Expr),
        Bits);

    switch (Expr) {
    case R_RELAX_GOT_PC:
    case R_RELAX_GOT_PC_NOPIC:
      Target->relaxGot(BufLoc, TargetVA);
      break;
    case R_RELAX_TLS_IE_TO_LE:
      Target->relaxTlsIeToLe(BufLoc, Type, TargetVA);
      break;
    case R_RELAX_TLS_LD_TO_LE:
    case R_RELAX_TLS_LD_TO_LE_ABS:
      Target->relaxTlsLdToLe(BufLoc, Type, TargetVA);
      break;
    case R_RELAX_TLS_GD_TO_LE:
    case R_RELAX_TLS_GD_TO_LE_NEG:
      Target->relaxTlsGdToLe(BufLoc, Type, TargetVA);
      break;
    case R_AARCH64_RELAX_TLS_GD_TO_IE_PAGE_PC:
    case R_RELAX_TLS_GD_TO_IE:
    case R_RELAX_TLS_GD_TO_IE_ABS:
    case R_RELAX_TLS_GD_TO_IE_GOT_OFF:
    case R_RELAX_TLS_GD_TO_IE_END:
      Target->relaxTlsGdToIe(BufLoc, Type, TargetVA);
      break;
    case R_PPC_CALL:
      // If this is a call to __tls_get_addr, it may be part of a TLS
      // sequence that has been relaxed and turned into a nop. In this
      // case, we don't want to handle it as a call.
      if (read32(BufLoc) == 0x60000000) // nop
        break;

      // Patch a nop (0x60000000) to a ld.
      if (Rel.Sym->NeedsTocRestore) {
        if (BufLoc + 8 > BufEnd || read32(BufLoc + 4) != 0x60000000) {
          error(getErrorLocation(BufLoc) + "call lacks nop, can't restore toc");
          break;
        }
        write32(BufLoc + 4, 0xe8410018); // ld %r2, 24(%r1)
      }
      Target->relocateOne(BufLoc, Type, TargetVA);
      break;
    default:
      Target->relocateOne(BufLoc, Type, TargetVA);
      break;
    }
  }
}

// For each function-defining prologue, find any calls to __morestack,
// and replace them with calls to __morestack_non_split.
static void switchMorestackCallsToMorestackNonSplit(
    DenseSet<Defined *> &Prologues, std::vector<Relocation *> &MorestackCalls) {

  // If the target adjusted a function's prologue, all calls to
  // __morestack inside that function should be switched to
  // __morestack_non_split.
  Symbol *MoreStackNonSplit = Symtab->find("__morestack_non_split");
  if (!MoreStackNonSplit) {
    error("Mixing split-stack objects requires a definition of "
          "__morestack_non_split");
    return;
  }

  // Sort both collections to compare addresses efficiently.
  llvm::sort(MorestackCalls, [](const Relocation *L, const Relocation *R) {
    return L->Offset < R->Offset;
  });
  std::vector<Defined *> Functions(Prologues.begin(), Prologues.end());
  llvm::sort(Functions, [](const Defined *L, const Defined *R) {
    return L->Value < R->Value;
  });

  auto It = MorestackCalls.begin();
  for (Defined *F : Functions) {
    // Find the first call to __morestack within the function.
    while (It != MorestackCalls.end() && (*It)->Offset < F->Value)
      ++It;
    // Adjust all calls inside the function.
    while (It != MorestackCalls.end() && (*It)->Offset < F->Value + F->Size) {
      (*It)->Sym = MoreStackNonSplit;
      ++It;
    }
  }
}

static bool enclosingPrologueAttempted(uint64_t Offset,
                                       const DenseSet<Defined *> &Prologues) {
  for (Defined *F : Prologues)
    if (F->Value <= Offset && Offset < F->Value + F->Size)
      return true;
  return false;
}

// If a function compiled for split stack calls a function not
// compiled for split stack, then the caller needs its prologue
// adjusted to ensure that the called function will have enough stack
// available. Find those functions, and adjust their prologues.
template <class ELFT>
void InputSectionBase::adjustSplitStackFunctionPrologues(uint8_t *Buf,
                                                         uint8_t *End) {
  if (!getFile<ELFT>()->SplitStack)
    return;
  DenseSet<Defined *> Prologues;
  std::vector<Relocation *> MorestackCalls;

  for (Relocation &Rel : Relocations) {
    // Local symbols can't possibly be cross-calls, and should have been
    // resolved long before this line.
    if (Rel.Sym->isLocal())
      continue;

    // Ignore calls into the split-stack api.
    if (Rel.Sym->getName().startswith("__morestack")) {
      if (Rel.Sym->getName().equals("__morestack"))
        MorestackCalls.push_back(&Rel);
      continue;
    }

    // A relocation to non-function isn't relevant. Sometimes
    // __morestack is not marked as a function, so this check comes
    // after the name check.
    if (Rel.Sym->Type != STT_FUNC)
      continue;

    // If the callee's-file was compiled with split stack, nothing to do.  In
    // this context, a "Defined" symbol is one "defined by the binary currently
    // being produced". So an "undefined" symbol might be provided by a shared
    // library. It is not possible to tell how such symbols were compiled, so be
    // conservative.
    if (Defined *D = dyn_cast<Defined>(Rel.Sym))
      if (InputSection *IS = cast_or_null<InputSection>(D->Section))
        if (!IS || !IS->getFile<ELFT>() || IS->getFile<ELFT>()->SplitStack)
          continue;

    if (enclosingPrologueAttempted(Rel.Offset, Prologues))
      continue;

    if (Defined *F = getEnclosingFunction<ELFT>(Rel.Offset)) {
      Prologues.insert(F);
      if (Target->adjustPrologueForCrossSplitStack(Buf + getOffset(F->Value),
                                                   End, F->StOther))
        continue;
      if (!getFile<ELFT>()->SomeNoSplitStack)
        error(lld::toString(this) + ": " + F->getName() +
              " (with -fsplit-stack) calls " + Rel.Sym->getName() +
              " (without -fsplit-stack), but couldn't adjust its prologue");
    }
  }

  if (Target->NeedsMoreStackNonSplit)
    switchMorestackCallsToMorestackNonSplit(Prologues, MorestackCalls);
}

template <class ELFT> void InputSection::writeTo(uint8_t *Buf) {
  if (Type == SHT_NOBITS)
    return;

  if (auto *S = dyn_cast<SyntheticSection>(this)) {
    S->writeTo(Buf + OutSecOff);
    return;
  }

  // If -r or --emit-relocs is given, then an InputSection
  // may be a relocation section.
  if (Type == SHT_RELA) {
    copyRelocations<ELFT>(Buf + OutSecOff, getDataAs<typename ELFT::Rela>());
    return;
  }
  if (Type == SHT_REL) {
    copyRelocations<ELFT>(Buf + OutSecOff, getDataAs<typename ELFT::Rel>());
    return;
  }

  // If -r is given, we may have a SHT_GROUP section.
  if (Type == SHT_GROUP) {
    copyShtGroup<ELFT>(Buf + OutSecOff);
    return;
  }

  // If this is a compressed section, uncompress section contents directly
  // to the buffer.
  if (UncompressedSize >= 0) {
    size_t Size = UncompressedSize;
    if (Error E = zlib::uncompress(toStringRef(RawData),
                                   (char *)(Buf + OutSecOff), Size))
      fatal(toString(this) +
            ": uncompress failed: " + llvm::toString(std::move(E)));
    uint8_t *BufEnd = Buf + OutSecOff + Size;
    relocate<ELFT>(Buf, BufEnd);
    return;
  }

  // Copy section contents from source object file to output file
  // and then apply relocations.
  memcpy(Buf + OutSecOff, data().data(), data().size());
  uint8_t *BufEnd = Buf + OutSecOff + data().size();
  relocate<ELFT>(Buf, BufEnd);
}

void InputSection::replace(InputSection *Other) {
  Alignment = std::max(Alignment, Other->Alignment);
  Other->Repl = Repl;
  Other->Live = false;
}

template <class ELFT>
EhInputSection::EhInputSection(ObjFile<ELFT> &F,
                               const typename ELFT::Shdr &Header,
                               StringRef Name)
    : InputSectionBase(F, Header, Name, InputSectionBase::EHFrame) {}

SyntheticSection *EhInputSection::getParent() const {
  return cast_or_null<SyntheticSection>(Parent);
}

// Returns the index of the first relocation that points to a region between
// Begin and Begin+Size.
template <class IntTy, class RelTy>
static unsigned getReloc(IntTy Begin, IntTy Size, const ArrayRef<RelTy> &Rels,
                         unsigned &RelocI) {
  // Start search from RelocI for fast access. That works because the
  // relocations are sorted in .eh_frame.
  for (unsigned N = Rels.size(); RelocI < N; ++RelocI) {
    const RelTy &Rel = Rels[RelocI];
    if (Rel.r_offset < Begin)
      continue;

    if (Rel.r_offset < Begin + Size)
      return RelocI;
    return -1;
  }
  return -1;
}

// .eh_frame is a sequence of CIE or FDE records.
// This function splits an input section into records and returns them.
template <class ELFT> void EhInputSection::split() {
  if (AreRelocsRela)
    split<ELFT>(relas<ELFT>());
  else
    split<ELFT>(rels<ELFT>());
}

template <class ELFT, class RelTy>
void EhInputSection::split(ArrayRef<RelTy> Rels) {
  unsigned RelI = 0;
  for (size_t Off = 0, End = data().size(); Off != End;) {
    size_t Size = readEhRecordSize(this, Off);
    Pieces.emplace_back(Off, this, Size, getReloc(Off, Size, Rels, RelI));
    // The empty record is the end marker.
    if (Size == 4)
      break;
    Off += Size;
  }
}

static size_t findNull(StringRef S, size_t EntSize) {
  // Optimize the common case.
  if (EntSize == 1)
    return S.find(0);

  for (unsigned I = 0, N = S.size(); I != N; I += EntSize) {
    const char *B = S.begin() + I;
    if (std::all_of(B, B + EntSize, [](char C) { return C == 0; }))
      return I;
  }
  return StringRef::npos;
}

SyntheticSection *MergeInputSection::getParent() const {
  return cast_or_null<SyntheticSection>(Parent);
}

// Split SHF_STRINGS section. Such section is a sequence of
// null-terminated strings.
void MergeInputSection::splitStrings(ArrayRef<uint8_t> Data, size_t EntSize) {
  size_t Off = 0;
  bool IsAlloc = Flags & SHF_ALLOC;
  StringRef S = toStringRef(Data);

  while (!S.empty()) {
    size_t End = findNull(S, EntSize);
    if (End == StringRef::npos)
      fatal(toString(this) + ": string is not null terminated");
    size_t Size = End + EntSize;

    Pieces.emplace_back(Off, xxHash64(S.substr(0, Size)), !IsAlloc);
    S = S.substr(Size);
    Off += Size;
  }
}

// Split non-SHF_STRINGS section. Such section is a sequence of
// fixed size records.
void MergeInputSection::splitNonStrings(ArrayRef<uint8_t> Data,
                                        size_t EntSize) {
  size_t Size = Data.size();
  assert((Size % EntSize) == 0);
  bool IsAlloc = Flags & SHF_ALLOC;

  for (size_t I = 0; I != Size; I += EntSize)
    Pieces.emplace_back(I, xxHash64(Data.slice(I, EntSize)), !IsAlloc);
}

template <class ELFT>
MergeInputSection::MergeInputSection(ObjFile<ELFT> &F,
                                     const typename ELFT::Shdr &Header,
                                     StringRef Name)
    : InputSectionBase(F, Header, Name, InputSectionBase::Merge) {}

MergeInputSection::MergeInputSection(uint64_t Flags, uint32_t Type,
                                     uint64_t Entsize, ArrayRef<uint8_t> Data,
                                     StringRef Name)
    : InputSectionBase(nullptr, Flags, Type, Entsize, /*Link*/ 0, /*Info*/ 0,
                       /*Alignment*/ Entsize, Data, Name, SectionBase::Merge) {}

// This function is called after we obtain a complete list of input sections
// that need to be linked. This is responsible to split section contents
// into small chunks for further processing.
//
// Note that this function is called from parallelForEach. This must be
// thread-safe (i.e. no memory allocation from the pools).
void MergeInputSection::splitIntoPieces() {
  assert(Pieces.empty());

  if (Flags & SHF_STRINGS)
    splitStrings(data(), Entsize);
  else
    splitNonStrings(data(), Entsize);
}

SectionPiece *MergeInputSection::getSectionPiece(uint64_t Offset) {
  if (this->data().size() <= Offset)
    fatal(toString(this) + ": offset is outside the section");

  // If Offset is not at beginning of a section piece, it is not in the map.
  // In that case we need to  do a binary search of the original section piece vector.
  auto It2 =
      llvm::upper_bound(Pieces, Offset, [](uint64_t Offset, SectionPiece P) {
        return Offset < P.InputOff;
      });
  return &It2[-1];
}

// Returns the offset in an output section for a given input offset.
// Because contents of a mergeable section is not contiguous in output,
// it is not just an addition to a base output offset.
uint64_t MergeInputSection::getParentOffset(uint64_t Offset) const {
  // If Offset is not at beginning of a section piece, it is not in the map.
  // In that case we need to search from the original section piece vector.
  const SectionPiece &Piece =
      *(const_cast<MergeInputSection *>(this)->getSectionPiece (Offset));
  uint64_t Addend = Offset - Piece.InputOff;
  return Piece.OutputOff + Addend;
}

template InputSection::InputSection(ObjFile<ELF32LE> &, const ELF32LE::Shdr &,
                                    StringRef);
template InputSection::InputSection(ObjFile<ELF32BE> &, const ELF32BE::Shdr &,
                                    StringRef);
template InputSection::InputSection(ObjFile<ELF64LE> &, const ELF64LE::Shdr &,
                                    StringRef);
template InputSection::InputSection(ObjFile<ELF64BE> &, const ELF64BE::Shdr &,
                                    StringRef);

template std::string InputSectionBase::getLocation<ELF32LE>(uint64_t);
template std::string InputSectionBase::getLocation<ELF32BE>(uint64_t);
template std::string InputSectionBase::getLocation<ELF64LE>(uint64_t);
template std::string InputSectionBase::getLocation<ELF64BE>(uint64_t);

template void InputSection::writeTo<ELF32LE>(uint8_t *);
template void InputSection::writeTo<ELF32BE>(uint8_t *);
template void InputSection::writeTo<ELF64LE>(uint8_t *);
template void InputSection::writeTo<ELF64BE>(uint8_t *);

template MergeInputSection::MergeInputSection(ObjFile<ELF32LE> &,
                                              const ELF32LE::Shdr &, StringRef);
template MergeInputSection::MergeInputSection(ObjFile<ELF32BE> &,
                                              const ELF32BE::Shdr &, StringRef);
template MergeInputSection::MergeInputSection(ObjFile<ELF64LE> &,
                                              const ELF64LE::Shdr &, StringRef);
template MergeInputSection::MergeInputSection(ObjFile<ELF64BE> &,
                                              const ELF64BE::Shdr &, StringRef);

template EhInputSection::EhInputSection(ObjFile<ELF32LE> &,
                                        const ELF32LE::Shdr &, StringRef);
template EhInputSection::EhInputSection(ObjFile<ELF32BE> &,
                                        const ELF32BE::Shdr &, StringRef);
template EhInputSection::EhInputSection(ObjFile<ELF64LE> &,
                                        const ELF64LE::Shdr &, StringRef);
template EhInputSection::EhInputSection(ObjFile<ELF64BE> &,
                                        const ELF64BE::Shdr &, StringRef);

template void EhInputSection::split<ELF32LE>();
template void EhInputSection::split<ELF32BE>();
template void EhInputSection::split<ELF64LE>();
template void EhInputSection::split<ELF64BE>();
