//===- 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 and
  // .eh_frame sections are smaller than 4 GiB.
  if ((sectionKind == SectionBase::Merge ||
       sectionKind == SectionBase::EHFrame) &&
      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);
}

uint64_t SectionBase::getRelocVA(uint64_t offset) const {
  if (auto *es = dyn_cast<EhInputSection>(this))
    return es->getParent()->getVA(offset);
  return getVA(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;
}

struct RISCVPCRel {
  static constexpr const char *loReloc = "R_RISCV_PCREL_LO12";
  static constexpr const char *hiReloc = "R_RISCV_PCREL_HI20";

  static bool isHiReloc(uint32_t type) {
    return is_contained({R_RISCV_PCREL_HI20, R_RISCV_GOT_HI20,
                         R_RISCV_TLS_GD_HI20, R_RISCV_TLS_GOT_HI20},
                        type);
  }
};

struct LoongArchPCAdd {
  static constexpr const char *loReloc = "R_LARCH_*PCADD_LO12";
  static constexpr const char *hiReloc = "R_LARCH_*PCADD_HI20";

  static bool isHiReloc(uint32_t type) {
    return is_contained({R_LARCH_PCADD_HI20, R_LARCH_GOT_PCADD_HI20,
                         R_LARCH_TLS_IE_PCADD_HI20, R_LARCH_TLS_LD_PCADD_HI20,
                         R_LARCH_TLS_GD_PCADD_HI20,
                         R_LARCH_TLS_DESC_PCADD_HI20},
                        type);
  }
};

// For PC-relative indirect relocations (e.g. R_RISCV_PCREL_LO12_* and
// R_LARCH_*PCADD_LO12), the symbol referenced by the LO12 relocation does not
// directly represent the final target address. Instead, it points to the
// corresponding HI20 relocation, and the target VA is computed using the
// symbol associated with that HI20 relocation.
//
// This helper locates and returns the matching HI20 relocation corresponding
// to a given LO12 relocation.
template <typename PCRel>
static Relocation *getPCRelHi20(Ctx &ctx, const InputSectionBase *loSec,
                                const Relocation &loReloc) {
  int64_t addend = loReloc.addend;
  Symbol *sym = loReloc.sym;

  const Defined *d = dyn_cast<Defined>(sym);
  if (!d) {
    Err(ctx) << loSec->getLocation(loReloc.offset)
             << " points to undefined symbol";
    return nullptr;
  }
  if (!d->section) {
    Err(ctx) << loSec->getLocation(loReloc.offset) << ": " << PCRel::loReloc
             << " 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) << ": " << PCRel::loReloc
             << " relocation points to a symbol '" << sym->getName()
             << "' in a different section '" << hiSec->name << "'";
    return nullptr;
  }

  if (addend != 0)
    Warn(ctx) << loSec->getLocation(loReloc.offset) << ": non-zero addend in "
              << PCRel::loReloc << " 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 + addend;
  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 (PCRel::isHiReloc(it->type))
      return &*it;

  Err(ctx) << loSec->getLocation(loReloc.offset) << ": " << PCRel::loReloc
           << " relocation points to " << hiSec->getObjMsg(d->value)
           << " without an associated " << PCRel::hiReloc << " 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:
    // For TLSDESC=>IE, R_RISCV_TLSDESC_{LOAD_LO12,ADD_LO12_I,CALL} reference
    // a non-TLS label and reach here.
    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_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_ADDEND_NEG:
    return -static_cast<uint64_t>(a);
  case R_RELAX_HINT:
    return 0;
  case RE_ARM_SBREL:
    return r.sym->getVA(ctx, a) - getARMStaticBase(*r.sym);
  case R_GOT:
    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:
    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:
    return r.sym->getGotVA(ctx) + a - ctx.in.gotPlt->getVA();
  case R_TLSLD_GOT_OFF:
  case R_GOT_OFF:
    return r.sym->getGotOffset(ctx) + a;
  case RE_AARCH64_GOT_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:
    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:
    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 = getPCRelHi20<RISCVPCRel>(ctx, this, r))
      return getRelocTargetVA(ctx, *hiRel, r.sym->getVA(ctx));
    return 0;
  }
  case RE_LOONGARCH_PC_INDIRECT: {
    if (const Relocation *hiRel = getPCRelHi20<LoongArchPCAdd>(ctx, this, r))
      return getRelocTargetVA(ctx, *hiRel, r.sym->getVA(ctx, a));
    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:
    return r.sym->getVA(ctx, a) - p;
  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_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:
    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:
    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_ULEB128";
      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);

  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;
    if (id == 0) {
      cies.emplace_back(off, size, firstRel, -1);
    } else {
      auto cieOff = off + 4 - id;
      auto it = partition_point(
          cies, [=](const EhSectionPiece &p) { return p.inputOff < cieOff; });
      if (it == cies.end() || it->inputOff != cieOff) {
        msg = "invalid CIE reference";
        break;
      }
      fdes.emplace_back(off, size, firstRel, it - cies.begin());
    }
    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) {
  // Pre-resolved by splitSections: pieceIdx + 1 in upper bits,
  // intra-piece offset in lower bits.
  if (uint32_t idx = offset >> mergeValueShift)
    return pieces[idx - 1];
  assert(offset < content().size());
  // For non-string fixed-size records, piece index = offset / entsize.
  if (!(flags & SHF_STRINGS))
    return pieces[offset / entsize];
  // Find the last piece whose inputOff <= offset. Prefer a conditional move
  // to a mispredicated branch.
  SectionPiece *p = pieces.data();
  for (size_t n = pieces.size(); n > 1; n -= n / 2)
    p = LLVM_UNPREDICTABLE(p[n / 2].inputOff <= offset) ? p + n / 2 : p;
  return *p;
}

// Return the offset in an output section for a given input offset.
uint64_t MergeInputSection::getParentOffset(uint64_t offset) const {
  // Pre-resolved by splitSections: pieceIdx + 1 in upper bits,
  // intra-piece offset in lower bits.
  if (uint32_t idx = offset >> mergeValueShift)
    return pieces[idx - 1].outputOff +
           (offset & llvm::maskTrailingOnes<uint64_t>(mergeValueShift));
  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>();
