//===- 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 "InputFiles.h"
#include "OutputSections.h"
#include "Relocations.h"
#include "SymbolTable.h"
#include "Symbols.h"
#include "SyntheticSections.h"
#include "Target.h"
#include "lld/Common/DWARF.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Compression.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/LEB128.h"
#include "llvm/Support/xxhash.h"
#include <algorithm>
#include <optional>
#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;

// Returns a string to construct an error message.
std::string elf::toStr(Ctx &ctx, const InputSectionBase *sec) {
  return (toStr(ctx, sec->file) + ":(" + sec->name + ")").str();
}

const ELFSyncStream &elf::operator<<(const ELFSyncStream &s,
                                     const InputSectionBase *sec) {
  return s << toStr(s.ctx, sec);
}

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

InputSectionBase::InputSectionBase(InputFile *file, StringRef name,
                                   uint32_t type, uint64_t flags, uint32_t link,
                                   uint32_t info, uint32_t addralign,
                                   uint32_t entsize, ArrayRef<uint8_t> data,
                                   Kind sectionKind)
    : SectionBase(sectionKind, file, name, type, flags, link, info, addralign,
                  entsize),
      bss(0), decodedCrel(0), keepUnique(0), nopFiller(0),
      content_(data.data()), size(data.size()) {
  // 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 && content().size() > UINT32_MAX)
    ErrAlways(getCtx()) << this << ": section too large";

  // The ELF spec states that a value of 0 means the section has
  // no alignment constraints.
  uint32_t v = std::max<uint32_t>(addralign, 1);
  if (!isPowerOf2_64(v)) {
    Err(getCtx()) << this << ": sh_addralign is not a power of 2";
    v = 1;
  }
  this->addralign = v;

  // If SHF_COMPRESSED is set, parse the header. The legacy .zdebug format is no
  // longer supported.
  if (flags & SHF_COMPRESSED) {
    Ctx &ctx = file->ctx;
    invokeELFT(parseCompressedHeader, ctx);
  }
}

// SHF_INFO_LINK and SHF_GROUP are normally resolved and not copied to the
// output section. However, for relocatable linking without
// --force-group-allocation, the SHF_GROUP flag and section groups are retained.
static uint64_t getFlags(Ctx &ctx, uint64_t flags) {
  flags &= ~(uint64_t)SHF_INFO_LINK;
  if (ctx.arg.resolveGroups)
    flags &= ~(uint64_t)SHF_GROUP;
  return flags;
}

template <class ELFT>
InputSectionBase::InputSectionBase(ObjFile<ELFT> &file,
                                   const typename ELFT::Shdr &hdr,
                                   StringRef name, Kind sectionKind)
    : InputSectionBase(&file, name, hdr.sh_type,
                       getFlags(file.ctx, hdr.sh_flags), hdr.sh_link,
                       hdr.sh_info, hdr.sh_addralign, hdr.sh_entsize,
                       getSectionContents(file, hdr), 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) {
    Err(getCtx()) << &file << ": section sh_addralign is too large";
    addralign = 1;
  }
}

size_t InputSectionBase::getSize() const {
  if (auto *s = dyn_cast<SyntheticSection>(this))
    return s->getSize();
  return size - bytesDropped;
}

template <class ELFT>
static void decompressAux(Ctx &ctx, const InputSectionBase &sec, uint8_t *out,
                          size_t size) {
  auto *hdr = reinterpret_cast<const typename ELFT::Chdr *>(sec.content_);
  auto compressed = ArrayRef<uint8_t>(sec.content_, sec.compressedSize)
                        .slice(sizeof(typename ELFT::Chdr));
  if (Error e = hdr->ch_type == ELFCOMPRESS_ZLIB
                    ? compression::zlib::decompress(compressed, out, size)
                    : compression::zstd::decompress(compressed, out, size))
    Err(ctx) << &sec << ": decompress failed: " << std::move(e);
}

void InputSectionBase::decompress() const {
  Ctx &ctx = getCtx();
  uint8_t *buf = makeThreadLocalN<uint8_t>(size);
  invokeELFT(decompressAux, ctx, *this, buf, size);
  content_ = buf;
  compressed = false;
}

template <class ELFT>
RelsOrRelas<ELFT> InputSectionBase::relsOrRelas(bool supportsCrel) const {
  if (relSecIdx == 0)
    return {};
  RelsOrRelas<ELFT> ret;
  auto *f = cast<ObjFile<ELFT>>(file);
  typename ELFT::Shdr shdr = f->template getELFShdrs<ELFT>()[relSecIdx];
  if (shdr.sh_type == SHT_CREL) {
    // Return an iterator if supported by caller.
    if (supportsCrel) {
      ret.crels = Relocs<typename ELFT::Crel>(
          (const uint8_t *)f->mb.getBufferStart() + shdr.sh_offset);
      return ret;
    }
    InputSectionBase *const &relSec = f->getSections()[relSecIdx];
    // Otherwise, allocate a buffer to hold the decoded RELA relocations. When
    // called for the first time, relSec is null (without --emit-relocs) or an
    // InputSection with false decodedCrel.
    if (!relSec || !cast<InputSection>(relSec)->decodedCrel) {
      auto *sec = makeThreadLocal<InputSection>(*f, shdr, name);
      f->cacheDecodedCrel(relSecIdx, sec);
      sec->type = SHT_RELA;
      sec->decodedCrel = true;

      RelocsCrel<ELFT::Is64Bits> entries(sec->content_);
      sec->size = entries.size() * sizeof(typename ELFT::Rela);
      auto *relas = makeThreadLocalN<typename ELFT::Rela>(entries.size());
      sec->content_ = reinterpret_cast<uint8_t *>(relas);
      for (auto [i, r] : llvm::enumerate(entries)) {
        relas[i].r_offset = r.r_offset;
        relas[i].setSymbolAndType(r.r_symidx, r.r_type, false);
        relas[i].r_addend = r.r_addend;
      }
    }
    ret.relas = {ArrayRef(
        reinterpret_cast<const typename ELFT::Rela *>(relSec->content_),
        relSec->size / sizeof(typename ELFT::Rela))};
    return ret;
  }

  const void *content = f->mb.getBufferStart() + shdr.sh_offset;
  size_t size = shdr.sh_size;
  if (shdr.sh_type == SHT_REL) {
    ret.rels = {ArrayRef(reinterpret_cast<const typename ELFT::Rel *>(content),
                         size / sizeof(typename ELFT::Rel))};
  } else {
    assert(shdr.sh_type == SHT_RELA);
    ret.relas = {
        ArrayRef(reinterpret_cast<const typename ELFT::Rela *>(content),
                 size / sizeof(typename ELFT::Rela))};
  }
  return ret;
}

Ctx &SectionBase::getCtx() const { return file->ctx; }

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 Class:
    llvm_unreachable("section classes do not have offsets");
  case Regular:
  case Synthetic:
  case Spill:
    return cast<InputSection>(this)->outSecOff + offset;
  case EHFrame: {
    // Two code paths may reach here. First, clang_rt.crtbegin.o and GCC
    // crtbeginT.o may reference the start of an empty .eh_frame to identify the
    // start of the output .eh_frame. Just return offset.
    //
    // Second, InputSection::copyRelocations on .eh_frame. Some pieces may be
    // discarded due to GC/ICF. We should compute the output section offset.
    const EhInputSection *es = cast<EhInputSection>(this);
    if (!es->content().empty())
      if (InputSection *isec = es->getParent())
        return isec->outSecOff + es->getParentOffset(offset);
    return offset;
  }
  case Merge:
    const MergeInputSection *ms = cast<MergeInputSection>(this);
    if (InputSection *isec = ms->getParent())
      return isec->outSecOff + 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 *isec = dyn_cast<InputSection>(this))
    sec = isec;
  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`.
template <typename ELFT>
void InputSectionBase::parseCompressedHeader(Ctx &ctx) {
  flags &= ~(uint64_t)SHF_COMPRESSED;

  // New-style header
  if (content().size() < sizeof(typename ELFT::Chdr)) {
    ErrAlways(ctx) << this << ": corrupted compressed section";
    return;
  }

  auto *hdr = reinterpret_cast<const typename ELFT::Chdr *>(content().data());
  if (hdr->ch_type == ELFCOMPRESS_ZLIB) {
    if (!compression::zlib::isAvailable())
      ErrAlways(ctx) << this
                     << " is compressed with ELFCOMPRESS_ZLIB, but lld is "
                        "not built with zlib support";
  } else if (hdr->ch_type == ELFCOMPRESS_ZSTD) {
    if (!compression::zstd::isAvailable())
      ErrAlways(ctx) << this
                     << " is compressed with ELFCOMPRESS_ZSTD, but lld is "
                        "not built with zstd support";
  } else {
    ErrAlways(ctx) << this << ": unsupported compression type ("
                   << uint32_t(hdr->ch_type) << ")";
    return;
  }

  compressed = true;
  compressedSize = size;
  size = hdr->ch_size;
  addralign = std::max<uint32_t>(hdr->ch_addralign, 1);
}

InputSection *InputSectionBase::getLinkOrderDep() const {
  assert(flags & SHF_LINK_ORDER);
  if (!link)
    return nullptr;
  return cast<InputSection>(file->getSections()[link]);
}

// Find a symbol that encloses a given location.
Defined *InputSectionBase::getEnclosingSymbol(uint64_t offset,
                                              uint8_t type) const {
  if (file->isInternal())
    return nullptr;
  for (Symbol *b : file->getSymbols())
    if (Defined *d = dyn_cast<Defined>(b))
      if (d->section == this && d->value <= offset &&
          offset < d->value + d->size && (type == 0 || type == d->type))
        return d;
  return nullptr;
}

// Returns an object file location string. Used to construct an error message.
std::string InputSectionBase::getLocation(uint64_t offset) const {
  std::string secAndOffset =
      (name + "+0x" + Twine::utohexstr(offset) + ")").str();

  std::string filename = toStr(getCtx(), file);
  if (Defined *d = getEnclosingFunction(offset))
    return filename + ":(function " + toStr(getCtx(), *d) + ": " + secAndOffset;

  return filename + ":(" + secAndOffset;
}

static void printFileLine(const ELFSyncStream &s, StringRef path,
                          unsigned line) {
  StringRef filename = path::filename(path);
  s << filename << ':' << line;
  if (filename != path)
    s << " (" << path << ':' << line << ')';
}

// Print an error message that looks like this:
//
//   foo.c:42 (/home/alice/possibly/very/long/path/foo.c:42)
const ELFSyncStream &elf::operator<<(const ELFSyncStream &s,
                                     InputSectionBase::SrcMsg &&msg) {
  auto &sec = msg.sec;
  if (sec.file->kind() != InputFile::ObjKind)
    return s;
  auto &file = cast<ELFFileBase>(*sec.file);

  // First, look up the DWARF line table.
  ArrayRef<InputSectionBase *> sections = file.getSections();
  auto it = llvm::find(sections, &sec);
  uint64_t sectionIndex = it != sections.end()
                              ? it - sections.begin()
                              : object::SectionedAddress::UndefSection;
  DWARFCache *dwarf = file.getDwarf();
  if (auto info = dwarf->getDILineInfo(msg.offset, sectionIndex))
    printFileLine(s, info->FileName, info->Line);
  else if (auto fileLine = dwarf->getVariableLoc(msg.sym.getName()))
    // If it failed, look up again as a variable.
    printFileLine(s, fileLine->first, fileLine->second);
  else
    // File.sourceFile contains STT_FILE symbol, and that is a last resort.
    s << file.sourceFile;
  return s;
}

// 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
const ELFSyncStream &elf::operator<<(const ELFSyncStream &s,
                                     InputSectionBase::ObjMsg &&msg) {
  auto *sec = msg.sec;
  s << sec->file->getName() << ":(";

  // Find a symbol that encloses a given location. getObjMsg may be called
  // before ObjFile::initSectionsAndLocalSyms where local symbols are
  // initialized.
  if (Defined *d = sec->getEnclosingSymbol(msg.offset))
    s << d;
  else
    s << sec->name << "+0x" << Twine::utohexstr(msg.offset);
  s << ')';
  if (!sec->file->archiveName.empty())
    s << (" in archive " + sec->file->archiveName).str();
  return s;
}

PotentialSpillSection::PotentialSpillSection(const InputSectionBase &source,
                                             InputSectionDescription &isd)
    : InputSection(source.file, source.name, source.type, source.flags,
                   source.addralign, source.addralign, {}, SectionBase::Spill),
      isd(&isd) {}

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

InputSection::InputSection(InputFile *f, StringRef name, uint32_t type,
                           uint64_t flags, uint32_t addralign, uint32_t entsize,
                           ArrayRef<uint8_t> data, Kind k)
    : InputSectionBase(f, name, type, flags,
                       /*link=*/0, /*info=*/0, addralign, /*entsize=*/entsize,
                       data, k) {
  assert(f || this == &InputSection::discarded);
}

template <class ELFT>
InputSection::InputSection(ObjFile<ELFT> &f, const typename ELFT::Shdr &header,
                           StringRef name)
    : InputSectionBase(f, header, name, InputSectionBase::Regular) {}

// 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.
  using u32 = typename ELFT::Word;
  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. We also need to handle combined or discarded
  // members.
  ArrayRef<InputSectionBase *> sections = file->getSections();
  DenseSet<uint32_t> seen;
  for (uint32_t idx : from.slice(1)) {
    OutputSection *osec = sections[idx]->getOutputSection();
    if (osec && seen.insert(osec->sectionIndex).second)
      *to++ = osec->sectionIndex;
  }
}

InputSectionBase *InputSection::getRelocatedSection() const {
  if (file->isInternal() || !isStaticRelSecType(type))
    return nullptr;
  ArrayRef<InputSectionBase *> sections = file->getSections();
  return sections[info];
}

template <class ELFT, class RelTy>
void InputSection::copyRelocations(Ctx &ctx, uint8_t *buf) {
  bool linkerRelax =
      ctx.arg.relax && is_contained({EM_RISCV, EM_LOONGARCH}, ctx.arg.emachine);
  if (!ctx.arg.relocatable && (linkerRelax || ctx.arg.branchToBranch)) {
    // On LoongArch and RISC-V, relaxation might change relocations: copy
    // from internal ones that are updated by relaxation.
    InputSectionBase *sec = getRelocatedSection();
    copyRelocations<ELFT, RelTy>(
        ctx, buf,
        llvm::make_range(sec->relocations.begin(), sec->relocations.end()));
  } else {
    // Convert the raw relocations in the input section into Relocation objects
    // suitable to be used by copyRelocations below.
    struct MapRel {
      Ctx &ctx;
      const ObjFile<ELFT> &file;
      Relocation operator()(const RelTy &rel) const {
        // RelExpr is not used so set to a dummy value.
        return Relocation{R_NONE, rel.getType(ctx.arg.isMips64EL), rel.r_offset,
                          getAddend<ELFT>(rel), &file.getRelocTargetSym(rel)};
      }
    };

    using RawRels = ArrayRef<RelTy>;
    using MapRelIter =
        llvm::mapped_iterator<typename RawRels::iterator, MapRel>;
    auto mapRel = MapRel{ctx, *getFile<ELFT>()};
    RawRels rawRels = getDataAs<RelTy>();
    auto rels = llvm::make_range(MapRelIter(rawRels.begin(), mapRel),
                                 MapRelIter(rawRels.end(), mapRel));
    copyRelocations<ELFT, RelTy>(ctx, buf, rels);
  }
}

// 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, class RelIt>
void InputSection::copyRelocations(Ctx &ctx, uint8_t *buf,
                                   llvm::iterator_range<RelIt> rels) {
  const TargetInfo &target = *ctx.target;
  InputSectionBase *sec = getRelocatedSection();
  (void)sec->contentMaybeDecompress(); // uncompress if needed

  for (const Relocation &rel : rels) {
    RelType type = rel.type;
    const ObjFile<ELFT> *file = getFile<ELFT>();
    Symbol &sym = *rel.sym;

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

    if (RelTy::HasAddend)
      p->r_addend = rel.addend;

    // Output section VA is zero for -r, so r_offset is an offset within the
    // section, but for --emit-relocs it is a virtual address.
    p->r_offset = sec->getVA(rel.offset);
    p->setSymbolAndType(ctx.in.symTab->getSymbolIndex(sym), type,
                        ctx.arg.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. Also, don't warn
      // on .gcc_except_table and debug sections.
      //
      // See the comment in maybeReportUndefined for PPC32 .got2 and PPC64 .toc
      auto *d = dyn_cast<Defined>(&sym);
      if (!d) {
        if (!isDebugSection(*sec) && sec->name != ".eh_frame" &&
            sec->name != ".gcc_except_table" && sec->name != ".got2" &&
            sec->name != ".toc") {
          uint32_t secIdx = cast<Undefined>(sym).discardedSecIdx;
          Elf_Shdr_Impl<ELFT> sec = file->template getELFShdrs<ELFT>()[secIdx];
          Warn(ctx) << "relocation refers to a discarded section: "
                    << CHECK2(file->getObj().getSectionName(sec), file)
                    << "\n>>> referenced by " << getObjMsg(p->r_offset);
        }
        p->setSymbolAndType(0, 0, false);
        continue;
      }
      SectionBase *section = d->section;
      assert(section->isLive());

      int64_t addend = rel.addend;
      const uint8_t *bufLoc = sec->content().begin() + rel.offset;
      if (!RelTy::HasAddend)
        addend = target.getImplicitAddend(bufLoc, type);

      if (ctx.arg.emachine == EM_MIPS &&
          target.getRelExpr(type, sym, bufLoc) == RE_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 compiler 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::HasAddend)
        p->r_addend =
            sym.getVA(ctx, addend) - section->getOutputSection()->addr;
      // For SHF_ALLOC sections relocated by REL, append a relocation to
      // sec->relocations so that relocateAlloc transitively called by
      // writeSections will update the implicit addend. Non-SHF_ALLOC sections
      // utilize relocateNonAlloc to process raw relocations and do not need
      // this sec->relocations change.
      else if (ctx.arg.relocatable && (sec->flags & SHF_ALLOC) &&
               type != target.noneRel)
        sec->addReloc({R_ABS, type, rel.offset, addend, &sym});
    } else if (ctx.arg.emachine == EM_PPC && type == R_PPC_PLTREL24 &&
               p->r_addend >= 0x8000 && sec->file->ppc32Got2) {
      // Similar to R_MIPS_GPREL{16,32}. If the addend of R_PPC_PLTREL24
      // indicates that r30 is relative to the input section .got2
      // (r_addend>=0x8000), after linking, r30 should be relative to the output
      // section .got2 . To compensate for the shift, adjust r_addend by
      // ppc32Got->outSecOff.
      p->r_addend += sec->file->ppc32Got2->outSecOff;
    }
  }
}

// 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_JUMP8:
  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_ALU_PREL_11_0:
  case R_ARM_THM_MOVW_PREL_NC:
  case R_ARM_THM_MOVT_PREL:
  case R_ARM_THM_PC12:
    return p + a;
  // p + a is unrepresentable as negative immediates can't be encoded.
  case R_ARM_THM_PC8:
    return p;
  }
  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 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;
  // 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:
  case R_AARCH64_PLT32:
    return p;
  }
  llvm_unreachable("AArch64 pc-relative relocation expected\n");
}

static uint64_t getRISCVUndefinedRelativeWeakVA(uint64_t type, uint64_t p) {
  switch (type) {
  case R_RISCV_BRANCH:
  case R_RISCV_JAL:
  case R_RISCV_CALL:
  case R_RISCV_CALL_PLT:
  case R_RISCV_RVC_BRANCH:
  case R_RISCV_RVC_JUMP:
  case R_RISCV_PLT32:
    return p;
  default:
    return 0;
  }
}

// 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) {
    Err(os->ctx) << "SBREL relocation to " << sym.getName()
                 << " without static base";
    return 0;
  }
  return os->ptLoad->firstSec->addr;
}

// For RE_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 the
// R_RISCV_PCREL_LO12 relocation.
static Relocation *getRISCVPCRelHi20(Ctx &ctx, const InputSectionBase *loSec,
                                     const Relocation &loReloc) {
  uint64_t addend = loReloc.addend;
  Symbol *sym = loReloc.sym;

  const Defined *d = cast<Defined>(sym);
  if (!d->section) {
    Err(ctx) << loSec->getLocation(loReloc.offset)
             << ": R_RISCV_PCREL_LO12 relocation points to an absolute symbol: "
             << sym->getName();
    return nullptr;
  }
  InputSection *hiSec = cast<InputSection>(d->section);

  if (hiSec != loSec)
    Err(ctx) << loSec->getLocation(loReloc.offset)
             << ": R_RISCV_PCREL_LO12 relocation points to a symbol '"
             << sym->getName() << "' in a different section '" << hiSec->name
             << "'";

  if (addend != 0)
    Warn(ctx) << loSec->getLocation(loReloc.offset)
              << ": non-zero addend in R_RISCV_PCREL_LO12 relocation to "
              << hiSec->getObjMsg(d->value) << " is ignored";

  // Relocations are sorted by offset, so we can use std::equal_range to do
  // binary search.
  Relocation hiReloc;
  hiReloc.offset = d->value;
  auto range =
      std::equal_range(hiSec->relocs().begin(), hiSec->relocs().end(), hiReloc,
                       [](const Relocation &lhs, const Relocation &rhs) {
                         return lhs.offset < rhs.offset;
                       });

  for (auto it = range.first; it != range.second; ++it)
    if (it->type == R_RISCV_PCREL_HI20 || it->type == R_RISCV_GOT_HI20 ||
        it->type == R_RISCV_TLS_GD_HI20 || it->type == R_RISCV_TLS_GOT_HI20)
      return &*it;

  Err(ctx) << loSec->getLocation(loReloc.offset)
           << ": R_RISCV_PCREL_LO12 relocation points to "
           << hiSec->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(Ctx &ctx, const Symbol &s) {
  // On targets that support TLSDESC, _TLS_MODULE_BASE_@tpoff = 0.
  if (&s == ctx.sym.tlsModuleBase)
    return 0;

  // There are 2 TLS layouts. Among targets we support, x86 uses TLS Variant 2
  // while most others use Variant 1. At run time TP will be aligned to p_align.

  // Variant 1. TP will be followed by an optional gap (which is the size of 2
  // pointers on ARM/AArch64, 0 on other targets), followed by alignment
  // padding, then the static TLS blocks. The alignment padding is added so that
  // (TP + gap + padding) is congruent to p_vaddr modulo p_align.
  //
  // Variant 2. Static TLS blocks, followed by alignment padding are placed
  // before TP. The alignment padding is added so that (TP - padding -
  // p_memsz) is congruent to p_vaddr modulo p_align.
  PhdrEntry *tls = ctx.tlsPhdr;
  if (!tls) // Reported an error in getSymVA
    return 0;
  switch (ctx.arg.emachine) {
    // Variant 1.
  case EM_ARM:
  case EM_AARCH64:
    return s.getVA(ctx, 0) + ctx.arg.wordsize * 2 +
           ((tls->p_vaddr - ctx.arg.wordsize * 2) & (tls->p_align - 1));
  case EM_MIPS:
  case EM_PPC:
  case EM_PPC64:
    // Adjusted Variant 1. TP is placed with a displacement of 0x7000, which is
    // to allow a signed 16-bit offset to reach 0x1000 of TCB/thread-library
    // data and 0xf000 of the program's TLS segment.
    return s.getVA(ctx, 0) + (tls->p_vaddr & (tls->p_align - 1)) - 0x7000;
  case EM_LOONGARCH:
  case EM_RISCV:
    // See the comment in handleTlsRelocation. For TLSDESC=>IE,
    // R_RISCV_TLSDESC_{LOAD_LO12,ADD_LO12_I,CALL} also reach here. While
    // `tls` may be null, the return value is ignored.
    if (s.type != STT_TLS)
      return 0;
    return s.getVA(ctx, 0) + (tls->p_vaddr & (tls->p_align - 1));

    // Variant 2.
  case EM_HEXAGON:
  case EM_S390:
  case EM_SPARCV9:
  case EM_386:
  case EM_X86_64:
    return s.getVA(ctx, 0) - tls->p_memsz -
           ((-tls->p_vaddr - tls->p_memsz) & (tls->p_align - 1));
  default:
    llvm_unreachable("unhandled ctx.arg.emachine");
  }
}

uint64_t InputSectionBase::getRelocTargetVA(Ctx &ctx, const Relocation &r,
                                            uint64_t p) const {
  int64_t a = r.addend;
  switch (r.expr) {
  case R_ABS:
  case R_DTPREL:
  case R_RELAX_TLS_LD_TO_LE_ABS:
  case R_RELAX_GOT_PC_NOPIC:
  case RE_AARCH64_AUTH:
  case RE_RISCV_ADD:
  case RE_RISCV_LEB128:
    return r.sym->getVA(ctx, a);
  case R_ADDEND:
    return a;
  case R_RELAX_HINT:
    return 0;
  case RE_ARM_SBREL:
    return r.sym->getVA(ctx, a) - getARMStaticBase(*r.sym);
  case R_GOT:
  case RE_AARCH64_AUTH_GOT:
  case R_RELAX_TLS_GD_TO_IE_ABS:
    return r.sym->getGotVA(ctx) + a;
  case RE_LOONGARCH_GOT:
    // The LoongArch TLS GD relocs reuse the R_LARCH_GOT_PC_LO12 reloc r.type
    // for their page offsets. The arithmetics are different in the TLS case
    // so we have to duplicate some logic here.
    if (r.sym->hasFlag(NEEDS_TLSGD) && r.type != R_LARCH_TLS_IE_PC_LO12)
      // Like RE_LOONGARCH_TLSGD_PAGE_PC but taking the absolute value.
      return ctx.in.got->getGlobalDynAddr(*r.sym) + a;
    return r.sym->getGotVA(ctx) + a;
  case R_GOTONLY_PC:
    return ctx.in.got->getVA() + a - p;
  case R_GOTPLTONLY_PC:
    return ctx.in.gotPlt->getVA() + a - p;
  case R_GOTREL:
  case RE_PPC64_RELAX_TOC:
    return r.sym->getVA(ctx, a) - ctx.in.got->getVA();
  case R_GOTPLTREL:
    return r.sym->getVA(ctx, a) - ctx.in.gotPlt->getVA();
  case R_GOTPLT:
  case R_RELAX_TLS_GD_TO_IE_GOTPLT:
    return r.sym->getGotVA(ctx) + a - ctx.in.gotPlt->getVA();
  case R_TLSLD_GOT_OFF:
  case R_GOT_OFF:
  case R_RELAX_TLS_GD_TO_IE_GOT_OFF:
    return r.sym->getGotOffset(ctx) + a;
  case RE_AARCH64_GOT_PAGE_PC:
  case RE_AARCH64_AUTH_GOT_PAGE_PC:
  case RE_AARCH64_RELAX_TLS_GD_TO_IE_PAGE_PC:
    return getAArch64Page(r.sym->getGotVA(ctx) + a) - getAArch64Page(p);
  case RE_AARCH64_GOT_PAGE:
    return r.sym->getGotVA(ctx) + a - getAArch64Page(ctx.in.got->getVA());
  case R_GOT_PC:
  case RE_AARCH64_AUTH_GOT_PC:
  case R_RELAX_TLS_GD_TO_IE:
    return r.sym->getGotVA(ctx) + a - p;
  case R_GOTPLT_GOTREL:
    return r.sym->getGotPltVA(ctx) + a - ctx.in.got->getVA();
  case R_GOTPLT_PC:
    return r.sym->getGotPltVA(ctx) + a - p;
  case RE_LOONGARCH_GOT_PAGE_PC:
  case RE_LOONGARCH_RELAX_TLS_GD_TO_IE_PAGE_PC:
    if (r.sym->hasFlag(NEEDS_TLSGD))
      return getLoongArchPageDelta(ctx.in.got->getGlobalDynAddr(*r.sym) + a, p,
                                   r.type);
    return getLoongArchPageDelta(r.sym->getGotVA(ctx) + a, p, r.type);
  case RE_MIPS_GOTREL:
    return r.sym->getVA(ctx, a) - ctx.in.mipsGot->getGp(file);
  case RE_MIPS_GOT_GP:
    return ctx.in.mipsGot->getGp(file) + a;
  case RE_MIPS_GOT_GP_PC: {
    // R_MIPS_LO16 expression has RE_MIPS_GOT_GP_PC r.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-significant bit of the microMIPS symbol.
    uint64_t v = ctx.in.mipsGot->getGp(file) + a - p;
    if (r.type == R_MIPS_LO16 || r.type == R_MICROMIPS_LO16)
      v += 4;
    if (r.type == R_MICROMIPS_LO16 || r.type == R_MICROMIPS_HI16)
      v -= 1;
    return v;
  }
  case RE_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 ctx.in.mipsGot->getVA() +
           ctx.in.mipsGot->getPageEntryOffset(file, *r.sym, a) -
           ctx.in.mipsGot->getGp(file);
  case RE_MIPS_OSEC_LOCAL_PAGE:
    // This is used by the MIPS multi-GOT implementation. It relocates
    // addresses of 64kb pages that lie inside the output section that sym is
    // a representative for.
    return getMipsPageAddr(r.sym->getOutputSection()->addr) + a;
  case RE_MIPS_GOT_OFF:
  case RE_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 r.type.
    return ctx.in.mipsGot->getVA() +
           ctx.in.mipsGot->getSymEntryOffset(file, *r.sym, a) -
           ctx.in.mipsGot->getGp(file);
  case RE_MIPS_TLSGD:
    return ctx.in.mipsGot->getVA() +
           ctx.in.mipsGot->getGlobalDynOffset(file, *r.sym) -
           ctx.in.mipsGot->getGp(file);
  case RE_MIPS_TLSLD:
    return ctx.in.mipsGot->getVA() + ctx.in.mipsGot->getTlsIndexOffset(file) -
           ctx.in.mipsGot->getGp(file);
  case RE_AARCH64_PAGE_PC: {
    uint64_t val = r.sym->isUndefWeak() ? p + a : r.sym->getVA(ctx, a);
    return getAArch64Page(val) - getAArch64Page(p);
  }
  case RE_RISCV_PC_INDIRECT: {
    if (const Relocation *hiRel = getRISCVPCRelHi20(ctx, this, r))
      return getRelocTargetVA(ctx, *hiRel, r.sym->getVA(ctx));
    return 0;
  }
  case RE_LOONGARCH_PAGE_PC:
    return getLoongArchPageDelta(r.sym->getVA(ctx, a), p, r.type);
  case R_PC:
  case RE_ARM_PCA: {
    uint64_t dest;
    if (r.expr == RE_ARM_PCA)
      // Some PC relative ARM (Thumb) relocations align down the place.
      p = p & 0xfffffffc;
    if (r.sym->isUndefined()) {
      // On ARM and AArch64 a branch to an undefined weak resolves to the next
      // instruction, otherwise the place. On RISC-V, resolve an undefined weak
      // to the same instruction to cause an infinite loop (making the user
      // aware of the issue) while ensuring no overflow.
      // Note: if the symbol is hidden, its binding has been converted to local,
      // so we just check isUndefined() here.
      if (ctx.arg.emachine == EM_ARM)
        dest = getARMUndefinedRelativeWeakVA(r.type, a, p);
      else if (ctx.arg.emachine == EM_AARCH64)
        dest = getAArch64UndefinedRelativeWeakVA(r.type, p) + a;
      else if (ctx.arg.emachine == EM_PPC)
        dest = p;
      else if (ctx.arg.emachine == EM_RISCV)
        dest = getRISCVUndefinedRelativeWeakVA(r.type, p) + a;
      else
        dest = r.sym->getVA(ctx, a);
    } else {
      dest = r.sym->getVA(ctx, a);
    }
    return dest - p;
  }
  case R_PLT:
    return r.sym->getPltVA(ctx) + a;
  case R_PLT_PC:
  case RE_PPC64_CALL_PLT:
    return r.sym->getPltVA(ctx) + a - p;
  case RE_LOONGARCH_PLT_PAGE_PC:
    return getLoongArchPageDelta(r.sym->getPltVA(ctx) + a, p, r.type);
  case R_PLT_GOTPLT:
    return r.sym->getPltVA(ctx) + a - ctx.in.gotPlt->getVA();
  case R_PLT_GOTREL:
    return r.sym->getPltVA(ctx) + a - ctx.in.got->getVA();
  case RE_PPC32_PLTREL:
    // R_PPC_PLTREL24 uses the addend (usually 0 or 0x8000) to indicate r30
    // stores _GLOBAL_OFFSET_TABLE_ or .got2+0x8000. The addend is ignored for
    // target VA computation.
    return r.sym->getPltVA(ctx) - p;
  case RE_PPC64_CALL: {
    uint64_t symVA = r.sym->getVA(ctx, 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(ctx, r.sym->stOther);
  }
  case RE_PPC64_TOCBASE:
    return getPPC64TocBase(ctx) + a;
  case R_RELAX_GOT_PC:
  case RE_PPC64_RELAX_GOT_PC:
    return r.sym->getVA(ctx, 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_TPREL:
    // It is not very clear what to return if the symbol is undefined. With
    // --noinhibit-exec, even a non-weak undefined reference may reach here.
    // Just return A, which matches R_ABS, and the behavior of some dynamic
    // loaders.
    if (r.sym->isUndefined())
      return a;
    return getTlsTpOffset(ctx, *r.sym) + a;
  case R_RELAX_TLS_GD_TO_LE_NEG:
  case R_TPREL_NEG:
    if (r.sym->isUndefined())
      return a;
    return -getTlsTpOffset(ctx, *r.sym) + a;
  case R_SIZE:
    return r.sym->getSize() + a;
  case R_TLSDESC:
  case RE_AARCH64_AUTH_TLSDESC:
    return ctx.in.got->getTlsDescAddr(*r.sym) + a;
  case R_TLSDESC_PC:
    return ctx.in.got->getTlsDescAddr(*r.sym) + a - p;
  case R_TLSDESC_GOTPLT:
    return ctx.in.got->getTlsDescAddr(*r.sym) + a - ctx.in.gotPlt->getVA();
  case RE_AARCH64_TLSDESC_PAGE:
  case RE_AARCH64_AUTH_TLSDESC_PAGE:
    return getAArch64Page(ctx.in.got->getTlsDescAddr(*r.sym) + a) -
           getAArch64Page(p);
  case RE_LOONGARCH_TLSDESC_PAGE_PC:
    return getLoongArchPageDelta(ctx.in.got->getTlsDescAddr(*r.sym) + a, p,
                                 r.type);
  case R_TLSGD_GOT:
    return ctx.in.got->getGlobalDynOffset(*r.sym) + a;
  case R_TLSGD_GOTPLT:
    return ctx.in.got->getGlobalDynAddr(*r.sym) + a - ctx.in.gotPlt->getVA();
  case R_TLSGD_PC:
    return ctx.in.got->getGlobalDynAddr(*r.sym) + a - p;
  case RE_LOONGARCH_TLSGD_PAGE_PC:
    return getLoongArchPageDelta(ctx.in.got->getGlobalDynAddr(*r.sym) + a, p,
                                 r.type);
  case R_TLSLD_GOTPLT:
    return ctx.in.got->getVA() + ctx.in.got->getTlsIndexOff() + a -
           ctx.in.gotPlt->getVA();
  case R_TLSLD_GOT:
    return ctx.in.got->getTlsIndexOff() + a;
  case R_TLSLD_PC:
    return ctx.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
// treatment 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(Ctx &ctx, uint8_t *buf,
                                    Relocs<RelTy> rels) {
  const unsigned bits = sizeof(typename ELFT::uint) * 8;
  const TargetInfo &target = *ctx.target;
  const auto emachine = ctx.arg.emachine;
  const bool isDebug = isDebugSection(*this);
  const bool isDebugLine = isDebug && name == ".debug_line";
  std::optional<uint64_t> tombstone;
  if (isDebug) {
    if (name == ".debug_loc" || name == ".debug_ranges")
      tombstone = 1;
    else if (name == ".debug_names")
      tombstone = UINT64_MAX; // tombstone value
    else
      tombstone = 0;
  }
  for (const auto &patAndValue : llvm::reverse(ctx.arg.deadRelocInNonAlloc))
    if (patAndValue.first.match(this->name)) {
      tombstone = patAndValue.second;
      break;
    }

  const InputFile *f = this->file;
  for (auto it = rels.begin(), end = rels.end(); it != end; ++it) {
    const RelTy &rel = *it;
    const RelType type = rel.getType(ctx.arg.isMips64EL);
    const uint64_t offset = rel.r_offset;
    uint8_t *bufLoc = buf + offset;
    int64_t addend = getAddend<ELFT>(rel);
    if (!RelTy::HasAddend)
      addend += target.getImplicitAddend(bufLoc, type);

    Symbol &sym = f->getRelocTargetSym(rel);
    RelExpr expr = target.getRelExpr(type, sym, bufLoc);
    if (expr == R_NONE)
      continue;
    auto *ds = dyn_cast<Defined>(&sym);

    if (emachine == EM_RISCV && type == R_RISCV_SET_ULEB128) {
      if (++it != end &&
          it->getType(/*isMips64EL=*/false) == R_RISCV_SUB_ULEB128 &&
          it->r_offset == offset) {
        uint64_t val;
        if (!ds && tombstone) {
          val = *tombstone;
        } else {
          val = sym.getVA(ctx, addend) -
                (f->getRelocTargetSym(*it).getVA(ctx) + getAddend<ELFT>(*it));
        }
        if (overwriteULEB128(bufLoc, val) >= 0x80)
          Err(ctx) << getLocation(offset) << ": ULEB128 value " << val
                   << " exceeds available space; references '" << &sym << "'";
        continue;
      }
      Err(ctx) << getLocation(offset)
               << ": R_RISCV_SET_ULEB128 not paired with R_RISCV_SUB_SET128";
      return;
    }

    if (tombstone && (expr == R_ABS || expr == R_DTPREL)) {
      // Resolve relocations in .debug_* referencing (discarded symbols or ICF
      // folded section symbols) to a tombstone value. Resolving to addend is
      // unsatisfactory because the result address range may collide with a
      // valid range of low address, or leave multiple CUs claiming ownership of
      // the same range of code, which may confuse consumers.
      //
      // To address the problems, we use -1 as a tombstone value for most
      // .debug_* sections. We have to ignore the addend because we don't want
      // to resolve an address attribute (which may have a non-zero addend) to
      // -1+addend (wrap around to a low address).
      //
      // R_DTPREL type relocations represent an offset into the dynamic thread
      // vector. The computed value is st_value plus a non-negative offset.
      // Negative values are invalid, so -1 can be used as the tombstone value.
      //
      // If the referenced symbol is relative to a discarded section (due to
      // --gc-sections, COMDAT, etc), it has been converted to a Undefined.
      // `ds->folded` catches the ICF folded case. However, resolving a
      // relocation in .debug_line to -1 would stop debugger users from setting
      // breakpoints on the folded-in function, so exclude .debug_line.
      //
      // For pre-DWARF-v5 .debug_loc and .debug_ranges, -1 is a reserved value
      // (base address selection entry), use 1 (which is used by GNU ld for
      // .debug_ranges).
      //
      // TODO To reduce disruption, we use 0 instead of -1 as the tombstone
      // value. Enable -1 in a future release.
      if (!ds || (ds->folded && !isDebugLine)) {
        // If -z dead-reloc-in-nonalloc= is specified, respect it.
        uint64_t value = SignExtend64<bits>(*tombstone);
        // For a 32-bit local TU reference in .debug_names, X86_64::relocate
        // requires that the unsigned value for R_X86_64_32 is truncated to
        // 32-bit. Other 64-bit targets's don't discern signed/unsigned 32-bit
        // absolute relocations and do not need this change.
        if (emachine == EM_X86_64 && type == R_X86_64_32)
          value = static_cast<uint32_t>(value);
        target.relocateNoSym(bufLoc, type, value);
        continue;
      }
    }

    // For a relocatable link, content relocated by relocation types with an
    // explicit addend, such as RELA, remain unchanged and we can stop here.
    // While content relocated by relocation types with an implicit addend, such
    // as REL, needs the implicit addend updated.
    if (ctx.arg.relocatable && (RelTy::HasAddend || sym.type != STT_SECTION))
      continue;

    // R_ABS/R_DTPREL and some other relocations can be used from non-SHF_ALLOC
    // sections.
    if (LLVM_LIKELY(expr == R_ABS) || expr == R_DTPREL || expr == R_GOTPLTREL ||
        expr == RE_RISCV_ADD || expr == RE_ARM_SBREL) {
      target.relocateNoSym(bufLoc, type,
                           SignExtend64<bits>(sym.getVA(ctx, addend)));
      continue;
    }

    if (expr == R_SIZE) {
      target.relocateNoSym(bufLoc, type,
                           SignExtend64<bits>(sym.getSize() + addend));
      continue;
    }

    // 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-compatibility, we accept them with warnings. We
    // know Steel Bank Common Lisp as of 2018 have this bug.
    //
    // 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.
    bool isErr = expr != R_PC && !(emachine == EM_386 && type == R_386_GOTPC);
    {
      ELFSyncStream diag(ctx, isErr && !ctx.arg.noinhibitExec
                                  ? DiagLevel::Err
                                  : DiagLevel::Warn);
      diag << getLocation(offset) << ": has non-ABS relocation " << type
           << " against symbol '" << &sym << "'";
    }
    if (!isErr)
      target.relocateNoSym(
          bufLoc, type,
          SignExtend64<bits>(sym.getVA(ctx, addend - offset - outSecOff)));
  }
}

template <class ELFT>
void InputSection::relocate(Ctx &ctx, uint8_t *buf, uint8_t *bufEnd) {
  if ((flags & SHF_EXECINSTR) && LLVM_UNLIKELY(getFile<ELFT>()->splitStack))
    adjustSplitStackFunctionPrologues<ELFT>(ctx, buf, bufEnd);

  if (flags & SHF_ALLOC) {
    ctx.target->relocateAlloc(*this, buf);
    return;
  }

  auto *sec = cast<InputSection>(this);
  // For a relocatable link, also call relocateNonAlloc() to rewrite applicable
  // locations with tombstone values.
  invokeOnRelocs(*sec, sec->relocateNonAlloc<ELFT>, ctx, buf);
}

// For each function-defining prologue, find any calls to __morestack,
// and replace them with calls to __morestack_non_split.
static void switchMorestackCallsToMorestackNonSplit(
    Ctx &ctx, DenseSet<Defined *> &prologues,
    SmallVector<Relocation *, 0> &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 = ctx.symtab->find("__morestack_non_split");
  if (!moreStackNonSplit) {
    ErrAlways(ctx) << "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(Ctx &ctx, uint8_t *buf,
                                                         uint8_t *end) {
  DenseSet<Defined *> prologues;
  SmallVector<Relocation *, 0> morestackCalls;

  for (Relocation &rel : relocs()) {
    // Ignore calls into the split-stack api.
    if (rel.sym->getName().starts_with("__morestack")) {
      if (rel.sym->getName() == "__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 *isec = cast_or_null<InputSection>(d->section))
        if (!isec || !isec->getFile<ELFT>() || isec->getFile<ELFT>()->splitStack)
          continue;

    if (enclosingPrologueAttempted(rel.offset, prologues))
      continue;

    if (Defined *f = getEnclosingFunction(rel.offset)) {
      prologues.insert(f);
      if (ctx.target->adjustPrologueForCrossSplitStack(buf + f->value, end,
                                                       f->stOther))
        continue;
      if (!getFile<ELFT>()->someNoSplitStack)
        Err(ctx)
            << this << ": " << f->getName() << " (with -fsplit-stack) calls "
            << rel.sym->getName()
            << " (without -fsplit-stack), but couldn't adjust its prologue";
    }
  }

  if (ctx.target->needsMoreStackNonSplit)
    switchMorestackCallsToMorestackNonSplit(ctx, prologues, morestackCalls);
}

template <class ELFT> void InputSection::writeTo(Ctx &ctx, uint8_t *buf) {
  if (LLVM_UNLIKELY(type == SHT_NOBITS))
    return;
  // If -r or --emit-relocs is given, then an InputSection
  // may be a relocation section.
  if (LLVM_UNLIKELY(type == SHT_RELA)) {
    copyRelocations<ELFT, typename ELFT::Rela>(ctx, buf);
    return;
  }
  if (LLVM_UNLIKELY(type == SHT_REL)) {
    copyRelocations<ELFT, typename ELFT::Rel>(ctx, buf);
    return;
  }

  // If -r is given, we may have a SHT_GROUP section.
  if (LLVM_UNLIKELY(type == SHT_GROUP)) {
    copyShtGroup<ELFT>(buf);
    return;
  }

  // If this is a compressed section, uncompress section contents directly
  // to the buffer.
  if (compressed) {
    auto *hdr = reinterpret_cast<const typename ELFT::Chdr *>(content_);
    auto compressed = ArrayRef<uint8_t>(content_, compressedSize)
                          .slice(sizeof(typename ELFT::Chdr));
    size_t size = this->size;
    if (Error e = hdr->ch_type == ELFCOMPRESS_ZLIB
                      ? compression::zlib::decompress(compressed, buf, size)
                      : compression::zstd::decompress(compressed, buf, size))
      Err(ctx) << this << ": decompress failed: " << std::move(e);
    uint8_t *bufEnd = buf + size;
    relocate<ELFT>(ctx, buf, bufEnd);
    return;
  }

  // Copy section contents from source object file to output file
  // and then apply relocations.
  memcpy(buf, content().data(), content().size());
  relocate<ELFT>(ctx, buf, buf + content().size());
}

void InputSection::replace(InputSection *other) {
  addralign = std::max(addralign, other->addralign);

  // When a section is replaced with another section that was allocated to
  // another partition, the replacement section (and its associated sections)
  // need to be placed in the main partition so that both partitions will be
  // able to access it.
  if (partition != other->partition) {
    partition = 1;
    for (InputSection *isec : dependentSections)
      isec->partition = 1;
  }

  other->repl = repl;
  other->markDead();
}

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);
}

// .eh_frame is a sequence of CIE or FDE records.
// This function splits an input section into records and returns them.
// In rare cases (.eh_frame pieces are reordered by a linker script), the
// relocations may be unordered.
template <class ELFT> void EhInputSection::split() {
  const RelsOrRelas<ELFT> elfRels = relsOrRelas<ELFT>();
  if (elfRels.areRelocsCrel())
    preprocessRelocs<ELFT>(elfRels.crels);
  else if (elfRels.areRelocsRel())
    preprocessRelocs<ELFT>(elfRels.rels);
  else
    preprocessRelocs<ELFT>(elfRels.relas);

  // The loop below expects the relocations to be sorted by offset.
  auto cmp = [](const Relocation &a, const Relocation &b) {
    return a.offset < b.offset;
  };
  if (!llvm::is_sorted(rels, cmp))
    llvm::stable_sort(rels, cmp);

  ArrayRef<uint8_t> d = content();
  const char *msg = nullptr;
  unsigned relI = 0;
  while (!d.empty()) {
    if (d.size() < 4) {
      msg = "CIE/FDE too small";
      break;
    }
    uint64_t size = endian::read32<ELFT::Endianness>(d.data());
    if (size == 0) // ZERO terminator
      break;
    uint32_t id = endian::read32<ELFT::Endianness>(d.data() + 4);
    size += 4;
    if (LLVM_UNLIKELY(size > d.size())) {
      // If it is 0xFFFFFFFF, the next 8 bytes contain the size instead,
      // but we do not support that format yet.
      msg = size == UINT32_MAX + uint64_t(4)
                ? "CIE/FDE too large"
                : "CIE/FDE ends past the end of the section";
      break;
    }

    // Find the first relocation that points to [off,off+size). Relocations
    // have been sorted by r_offset.
    const uint64_t off = d.data() - content().data();
    while (relI != rels.size() && rels[relI].offset < off)
      ++relI;
    unsigned firstRel = -1;
    if (relI != rels.size() && rels[relI].offset < off + size)
      firstRel = relI;
    (id == 0 ? cies : fdes).emplace_back(off, this, size, firstRel);
    d = d.slice(size);
  }
  if (msg)
    Err(file->ctx) << "corrupted .eh_frame: " << msg << "\n>>> defined in "
                   << getObjMsg(d.data() - content().data());
}

template <class ELFT, class RelTy>
void EhInputSection::preprocessRelocs(Relocs<RelTy> elfRels) {
  Ctx &ctx = file->ctx;
  rels.reserve(elfRels.size());
  for (auto rel : elfRels) {
    uint64_t offset = rel.r_offset;
    Symbol &sym = file->getSymbol(rel.getSymbol(ctx.arg.isMips64EL));
    RelType type = rel.getType(ctx.arg.isMips64EL);
    RelExpr expr = ctx.target->getRelExpr(type, sym, content().data() + offset);
    int64_t addend =
        RelTy::HasAddend
            ? getAddend<ELFT>(rel)
            : ctx.target->getImplicitAddend(content().data() + offset, type);
    rels.push_back({expr, type, offset, addend, &sym});
  }
}

// Return the offset in an output section for a given input offset.
uint64_t EhInputSection::getParentOffset(uint64_t offset) const {
  auto it = partition_point(
      fdes, [=](EhSectionPiece p) { return p.inputOff <= offset; });
  if (it == fdes.begin() || it[-1].inputOff + it[-1].size <= offset) {
    it = partition_point(
        cies, [=](EhSectionPiece p) { return p.inputOff <= offset; });
    if (it == cies.begin()) // invalid piece
      return offset;
  }
  if (it[-1].outputOff == -1) // invalid piece
    return offset - it[-1].inputOff;
  return it[-1].outputOff + (offset - it[-1].inputOff);
}

static size_t findNull(StringRef s, size_t entSize) {
  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;
  }
  llvm_unreachable("");
}

// Split SHF_STRINGS section. Such section is a sequence of
// null-terminated strings.
void MergeInputSection::splitStrings(StringRef s, size_t entSize) {
  const bool live = !(flags & SHF_ALLOC) || !getCtx().arg.gcSections;
  const char *p = s.data(), *end = s.data() + s.size();
  if (!std::all_of(end - entSize, end, [](char c) { return c == 0; })) {
    Err(getCtx()) << this << ": string is not null terminated";
    pieces.emplace_back(entSize, 0, false);
    return;
  }
  if (entSize == 1) {
    // Optimize the common case.
    do {
      size_t size = strlen(p);
      pieces.emplace_back(p - s.begin(), xxh3_64bits(StringRef(p, size)), live);
      p += size + 1;
    } while (p != end);
  } else {
    do {
      size_t size = findNull(StringRef(p, end - p), entSize);
      pieces.emplace_back(p - s.begin(), xxh3_64bits(StringRef(p, size)), live);
      p += size + entSize;
    } while (p != end);
  }
}

// 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);
  const bool live = !(flags & SHF_ALLOC) || !getCtx().arg.gcSections;

  pieces.resize_for_overwrite(size / entSize);
  for (size_t i = 0, j = 0; i != size; i += entSize, j++)
    pieces[j] = {i, (uint32_t)xxh3_64bits(data.slice(i, entSize)), live};
}

template <class ELFT>
MergeInputSection::MergeInputSection(ObjFile<ELFT> &f,
                                     const typename ELFT::Shdr &header,
                                     StringRef name)
    : InputSectionBase(f, header, name, InputSectionBase::Merge) {}

MergeInputSection::MergeInputSection(Ctx &ctx, StringRef name, uint32_t type,
                                     uint64_t flags, uint64_t entsize,
                                     ArrayRef<uint8_t> data)
    : InputSectionBase(ctx.internalFile, name, type, flags, /*link=*/0,
                       /*info=*/0,
                       /*addralign=*/entsize, entsize, data,
                       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(toStringRef(contentMaybeDecompress()), entsize);
  else
    splitNonStrings(contentMaybeDecompress(), entsize);
}

SectionPiece &MergeInputSection::getSectionPiece(uint64_t offset) {
  if (content().size() <= offset) {
    Err(getCtx()) << this << ": offset is outside the section";
    return pieces[0];
  }
  return partition_point(
      pieces, [=](SectionPiece p) { return p.inputOff <= offset; })[-1];
}

// Return the offset in an output section for a given input offset.
uint64_t MergeInputSection::getParentOffset(uint64_t offset) const {
  const SectionPiece &piece = getSectionPiece(offset);
  return piece.outputOff + (offset - piece.inputOff);
}

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 void InputSection::writeTo<ELF32LE>(Ctx &, uint8_t *);
template void InputSection::writeTo<ELF32BE>(Ctx &, uint8_t *);
template void InputSection::writeTo<ELF64LE>(Ctx &, uint8_t *);
template void InputSection::writeTo<ELF64BE>(Ctx &, uint8_t *);

template RelsOrRelas<ELF32LE>
InputSectionBase::relsOrRelas<ELF32LE>(bool) const;
template RelsOrRelas<ELF32BE>
InputSectionBase::relsOrRelas<ELF32BE>(bool) const;
template RelsOrRelas<ELF64LE>
InputSectionBase::relsOrRelas<ELF64LE>(bool) const;
template RelsOrRelas<ELF64BE>
InputSectionBase::relsOrRelas<ELF64BE>(bool) const;

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>();
