//===- OutputSections.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 "OutputSections.h"
#include "Config.h"
#include "InputFiles.h"
#include "LinkerScript.h"
#include "Symbols.h"
#include "SyntheticSections.h"
#include "Target.h"
#include "lld/Common/Arrays.h"
#include "lld/Common/Memory.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/Config/llvm-config.h" // LLVM_ENABLE_ZLIB, LLVM_ENABLE_ZSTD
#include "llvm/Support/Compression.h"
#include "llvm/Support/LEB128.h"
#include "llvm/Support/Parallel.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/TimeProfiler.h"
#undef in
#if LLVM_ENABLE_ZLIB
// Avoid introducing max as a macro from Windows headers.
#define NOMINMAX
#include <zlib.h>
#endif
#if LLVM_ENABLE_ZSTD
#include <zstd.h>
#endif

using namespace llvm;
using namespace llvm::dwarf;
using namespace llvm::object;
using namespace llvm::support::endian;
using namespace llvm::ELF;
using namespace lld;
using namespace lld::elf;

uint32_t OutputSection::getPhdrFlags() const {
  uint32_t ret = 0;
  bool purecode =
      (ctx.arg.emachine == EM_ARM && (flags & SHF_ARM_PURECODE)) ||
      (ctx.arg.emachine == EM_AARCH64 && (flags & SHF_AARCH64_PURECODE));
  if (!purecode)
    ret |= PF_R;
  if (flags & SHF_WRITE)
    ret |= PF_W;
  if (flags & SHF_EXECINSTR)
    ret |= PF_X;
  return ret;
}

template <class ELFT>
void OutputSection::writeHeaderTo(typename ELFT::Shdr *shdr) {
  shdr->sh_entsize = entsize;
  shdr->sh_addralign = addralign;
  shdr->sh_type = type;
  shdr->sh_offset = offset;
  shdr->sh_flags = flags;
  shdr->sh_info = info;
  shdr->sh_link = link;
  shdr->sh_addr = addr;
  shdr->sh_size = size;
  shdr->sh_name = shName;
}

OutputSection::OutputSection(Ctx &ctx, StringRef name, uint32_t type,
                             uint64_t flags)
    : SectionBase(Output, ctx.internalFile, name, type, flags, /*link=*/0,
                  /*info=*/0, /*addralign=*/1, /*entsize=*/0),
      ctx(ctx) {}

uint64_t OutputSection::getLMA() const {
  return ptLoad ? addr + ptLoad->lmaOffset : addr;
}

// We allow sections of types listed below to merged into a
// single progbits section. This is typically done by linker
// scripts. Merging nobits and progbits will force disk space
// to be allocated for nobits sections. Other ones don't require
// any special treatment on top of progbits, so there doesn't
// seem to be a harm in merging them.
//
// NOTE: clang since rL252300 emits SHT_X86_64_UNWIND .eh_frame sections. Allow
// them to be merged into SHT_PROGBITS .eh_frame (GNU as .cfi_*).
static bool canMergeToProgbits(Ctx &ctx, unsigned type) {
  return type == SHT_NOBITS || type == SHT_PROGBITS || type == SHT_INIT_ARRAY ||
         type == SHT_PREINIT_ARRAY || type == SHT_FINI_ARRAY ||
         type == SHT_NOTE ||
         (type == SHT_X86_64_UNWIND && ctx.arg.emachine == EM_X86_64);
}

// Record that isec will be placed in the OutputSection. isec does not become
// permanent until finalizeInputSections() is called. The function should not be
// used after finalizeInputSections() is called. If you need to add an
// InputSection post finalizeInputSections(), then you must do the following:
//
// 1. Find or create an InputSectionDescription to hold InputSection.
// 2. Add the InputSection to the InputSectionDescription::sections.
// 3. Call commitSection(isec).
void OutputSection::recordSection(InputSectionBase *isec) {
  partition = isec->partition;
  isec->parent = this;
  if (commands.empty() || !isa<InputSectionDescription>(commands.back()))
    commands.push_back(make<InputSectionDescription>(""));
  auto *isd = cast<InputSectionDescription>(commands.back());
  isd->sectionBases.push_back(isec);
}

// Update fields (type, flags, alignment, etc) according to the InputSection
// isec. Also check whether the InputSection flags and type are consistent with
// other InputSections.
void OutputSection::commitSection(InputSection *isec) {
  if (LLVM_UNLIKELY(type != isec->type)) {
    if (!hasInputSections && !typeIsSet) {
      type = isec->type;
    } else if (isStaticRelSecType(type) && isStaticRelSecType(isec->type) &&
               (type == SHT_CREL) != (isec->type == SHT_CREL)) {
      // Combine mixed SHT_REL[A] and SHT_CREL to SHT_CREL.
      type = SHT_CREL;
      if (type == SHT_REL) {
        if (name.consume_front(".rel"))
          name = ctx.saver.save(".crel" + name);
      } else if (name.consume_front(".rela")) {
        name = ctx.saver.save(".crel" + name);
      }
    } else {
      if (typeIsSet || !canMergeToProgbits(ctx, type) ||
          !canMergeToProgbits(ctx, isec->type)) {
        // The (NOLOAD) changes the section type to SHT_NOBITS, the intention is
        // that the contents at that address is provided by some other means.
        // Some projects (e.g.
        // https://github.com/ClangBuiltLinux/linux/issues/1597) rely on the
        // behavior. Other types get an error.
        if (type != SHT_NOBITS) {
          Err(ctx) << "section type mismatch for " << isec->name << "\n>>> "
                   << isec << ": "
                   << getELFSectionTypeName(ctx.arg.emachine, isec->type)
                   << "\n>>> output section " << name << ": "
                   << getELFSectionTypeName(ctx.arg.emachine, type);
        }
      }
      if (!typeIsSet)
        type = SHT_PROGBITS;
    }
  }
  if (!hasInputSections) {
    // If IS is the first section to be added to this section,
    // initialize type, entsize and flags from isec.
    hasInputSections = true;
    entsize = isec->entsize;
    flags = isec->flags;
  } else {
    // Otherwise, check if new type or flags are compatible with existing ones.
    if ((flags ^ isec->flags) & SHF_TLS)
      ErrAlways(ctx) << "incompatible section flags for " << name << "\n>>> "
                     << isec << ": 0x" << utohexstr(isec->flags, true)
                     << "\n>>> output section " << name << ": 0x"
                     << utohexstr(flags, true);
  }

  isec->parent = this;
  uint64_t andMask = 0;
  if (ctx.arg.emachine == EM_ARM)
    andMask |= (uint64_t)SHF_ARM_PURECODE;
  if (ctx.arg.emachine == EM_AARCH64)
    andMask |= (uint64_t)SHF_AARCH64_PURECODE;
  uint64_t orMask = ~andMask;
  uint64_t andFlags = (flags & isec->flags) & andMask;
  uint64_t orFlags = (flags | isec->flags) & orMask;
  flags = andFlags | orFlags;
  if (nonAlloc)
    flags &= ~(uint64_t)SHF_ALLOC;

  addralign = std::max(addralign, isec->addralign);

  // If this section contains a table of fixed-size entries, sh_entsize
  // holds the element size. If it contains elements of different size we
  // set sh_entsize to 0.
  if (entsize != isec->entsize)
    entsize = 0;
}

static MergeSyntheticSection *createMergeSynthetic(Ctx &ctx, StringRef name,
                                                   uint32_t type,
                                                   uint64_t flags,
                                                   uint32_t addralign) {
  if ((flags & SHF_STRINGS) && ctx.arg.optimize >= 2)
    return make<MergeTailSection>(ctx, name, type, flags, addralign);
  return make<MergeNoTailSection>(ctx, name, type, flags, addralign);
}

// This function scans over the InputSectionBase list sectionBases to create
// InputSectionDescription::sections.
//
// It removes MergeInputSections from the input section array and adds
// new synthetic sections at the location of the first input section
// that it replaces. It then finalizes each synthetic section in order
// to compute an output offset for each piece of each input section.
void OutputSection::finalizeInputSections() {
  auto *script = ctx.script;
  std::vector<MergeSyntheticSection *> mergeSections;
  for (SectionCommand *cmd : commands) {
    auto *isd = dyn_cast<InputSectionDescription>(cmd);
    if (!isd)
      continue;
    isd->sections.reserve(isd->sectionBases.size());
    for (InputSectionBase *s : isd->sectionBases) {
      MergeInputSection *ms = dyn_cast<MergeInputSection>(s);
      if (!ms) {
        isd->sections.push_back(cast<InputSection>(s));
        continue;
      }

      // We do not want to handle sections that are not alive, so just remove
      // them instead of trying to merge.
      if (!ms->isLive())
        continue;

      auto i = llvm::find_if(mergeSections, [=](MergeSyntheticSection *sec) {
        // While we could create a single synthetic section for two different
        // values of Entsize, it is better to take Entsize into consideration.
        //
        // With a single synthetic section no two pieces with different Entsize
        // could be equal, so we may as well have two sections.
        //
        // Using Entsize in here also allows us to propagate it to the synthetic
        // section.
        //
        // SHF_STRINGS section with different alignments should not be merged.
        return sec->flags == ms->flags && sec->entsize == ms->entsize &&
               (sec->addralign == ms->addralign || !(sec->flags & SHF_STRINGS));
      });
      if (i == mergeSections.end()) {
        MergeSyntheticSection *syn = createMergeSynthetic(
            ctx, s->name, ms->type, ms->flags, ms->addralign);
        mergeSections.push_back(syn);
        i = std::prev(mergeSections.end());
        syn->entsize = ms->entsize;
        isd->sections.push_back(syn);
        // The merge synthetic section inherits the potential spill locations of
        // its first contained section.
        auto it = script->potentialSpillLists.find(ms);
        if (it != script->potentialSpillLists.end())
          script->potentialSpillLists.try_emplace(syn, it->second);
      }
      (*i)->addSection(ms);
    }

    // sectionBases should not be used from this point onwards. Clear it to
    // catch misuses.
    isd->sectionBases.clear();

    // Some input sections may be removed from the list after ICF.
    for (InputSection *s : isd->sections)
      commitSection(s);
  }
  for (auto *ms : mergeSections) {
    // Merging may have increased the alignment of a spillable section. Update
    // the alignment of potential spill sections and their containing output
    // sections.
    if (auto it = script->potentialSpillLists.find(ms);
        it != script->potentialSpillLists.end()) {
      for (PotentialSpillSection *s = it->second.head; s; s = s->next) {
        s->addralign = std::max(s->addralign, ms->addralign);
        s->parent->addralign = std::max(s->parent->addralign, s->addralign);
      }
    }

    ms->finalizeContents();
  }
}

static void sortByOrder(MutableArrayRef<InputSection *> in,
                        llvm::function_ref<int(InputSectionBase *s)> order) {
  std::vector<std::pair<int, InputSection *>> v;
  for (InputSection *s : in)
    v.emplace_back(order(s), s);
  llvm::stable_sort(v, less_first());

  for (size_t i = 0; i < v.size(); ++i)
    in[i] = v[i].second;
}

uint64_t elf::getHeaderSize(Ctx &ctx) {
  if (ctx.arg.oFormatBinary)
    return 0;
  return ctx.out.elfHeader->size + ctx.out.programHeaders->size;
}

void OutputSection::sort(llvm::function_ref<int(InputSectionBase *s)> order) {
  assert(isLive());
  for (SectionCommand *b : commands)
    if (auto *isd = dyn_cast<InputSectionDescription>(b))
      sortByOrder(isd->sections, order);
}

static void nopInstrFill(Ctx &ctx, uint8_t *buf, size_t size) {
  if (size == 0)
    return;
  unsigned i = 0;
  std::vector<std::vector<uint8_t>> nopFiller = *ctx.target->nopInstrs;
  unsigned num = size / nopFiller.back().size();
  for (unsigned c = 0; c < num; ++c) {
    memcpy(buf + i, nopFiller.back().data(), nopFiller.back().size());
    i += nopFiller.back().size();
  }
  unsigned remaining = size - i;
  if (!remaining)
    return;
  assert(nopFiller[remaining - 1].size() == remaining);
  memcpy(buf + i, nopFiller[remaining - 1].data(), remaining);
}

// Fill [Buf, Buf + Size) with Filler.
// This is used for linker script "=fillexp" command.
static void fill(uint8_t *buf, size_t size,
                 const std::array<uint8_t, 4> &filler) {
  size_t i = 0;
  for (; i + 4 < size; i += 4)
    memcpy(buf + i, filler.data(), 4);
  memcpy(buf + i, filler.data(), size - i);
}

#if LLVM_ENABLE_ZLIB
static SmallVector<uint8_t, 0> deflateShard(Ctx &ctx, ArrayRef<uint8_t> in,
                                            int level, int flush) {
  // 15 and 8 are default. windowBits=-15 is negative to generate raw deflate
  // data with no zlib header or trailer.
  z_stream s = {};
  auto res = deflateInit2(&s, level, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY);
  if (res != 0) {
    Err(ctx) << "--compress-sections: deflateInit2 returned " << res;
    return {};
  }
  s.next_in = const_cast<uint8_t *>(in.data());
  s.avail_in = in.size();

  // Allocate a buffer of half of the input size, and grow it by 1.5x if
  // insufficient.
  SmallVector<uint8_t, 0> out;
  size_t pos = 0;
  out.resize_for_overwrite(std::max<size_t>(in.size() / 2, 64));
  do {
    if (pos == out.size())
      out.resize_for_overwrite(out.size() * 3 / 2);
    s.next_out = out.data() + pos;
    s.avail_out = out.size() - pos;
    (void)deflate(&s, flush);
    pos = s.next_out - out.data();
  } while (s.avail_out == 0);
  assert(s.avail_in == 0);

  out.truncate(pos);
  deflateEnd(&s);
  return out;
}
#endif

// Compress certain non-SHF_ALLOC sections:
//
// * (if --compress-debug-sections is specified) non-empty .debug_* sections
// * (if --compress-sections is specified) matched sections
template <class ELFT> void OutputSection::maybeCompress(Ctx &ctx) {
  using Elf_Chdr = typename ELFT::Chdr;
  (void)sizeof(Elf_Chdr);

  DebugCompressionType ctype = DebugCompressionType::None;
  size_t compressedSize = sizeof(Elf_Chdr);
  unsigned level = 0; // default compression level
  if (!(flags & SHF_ALLOC) && ctx.arg.compressDebugSections &&
      name.starts_with(".debug_"))
    ctype = *ctx.arg.compressDebugSections;
  for (auto &[glob, t, l] : ctx.arg.compressSections)
    if (glob.match(name))
      std::tie(ctype, level) = {t, l};
  if (ctype == DebugCompressionType::None)
    return;
  if (flags & SHF_ALLOC) {
    Err(ctx) << "--compress-sections: section '" << name
             << "' with the SHF_ALLOC flag cannot be compressed";
    return;
  }

  llvm::TimeTraceScope timeScope("Compress sections");
  auto buf = std::make_unique<uint8_t[]>(size);
  // Write uncompressed data to a temporary zero-initialized buffer.
  {
    parallel::TaskGroup tg;
    writeTo<ELFT>(ctx, buf.get(), tg);
  }
  // The generic ABI specifies "The sh_size and sh_addralign fields of the
  // section header for a compressed section reflect the requirements of the
  // compressed section." However, 1-byte alignment has been wildly accepted
  // and utilized for a long time. Removing alignment padding is particularly
  // useful when there are many compressed output sections.
  addralign = 1;

  // Split input into 1-MiB shards.
  [[maybe_unused]] constexpr size_t shardSize = 1 << 20;
  auto shardsIn = split(ArrayRef<uint8_t>(buf.get(), size), shardSize);
  const size_t numShards = shardsIn.size();
  auto shardsOut = std::make_unique<SmallVector<uint8_t, 0>[]>(numShards);

#if LLVM_ENABLE_ZSTD
  // Use ZSTD's streaming compression API. See
  // http://facebook.github.io/zstd/zstd_manual.html "Streaming compression -
  // HowTo".
  if (ctype == DebugCompressionType::Zstd) {
    parallelFor(0, numShards, [&](size_t i) {
      SmallVector<uint8_t, 0> out;
      ZSTD_CCtx *cctx = ZSTD_createCCtx();
      ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, level);
      ZSTD_inBuffer zib = {shardsIn[i].data(), shardsIn[i].size(), 0};
      ZSTD_outBuffer zob = {nullptr, 0, 0};
      size_t size;
      do {
        // Allocate a buffer of half of the input size, and grow it by 1.5x if
        // insufficient.
        if (zob.pos == zob.size) {
          out.resize_for_overwrite(
              zob.size ? zob.size * 3 / 2 : std::max<size_t>(zib.size / 4, 64));
          zob = {out.data(), out.size(), zob.pos};
        }
        size = ZSTD_compressStream2(cctx, &zob, &zib, ZSTD_e_end);
        assert(!ZSTD_isError(size));
      } while (size != 0);
      out.truncate(zob.pos);
      ZSTD_freeCCtx(cctx);
      shardsOut[i] = std::move(out);
    });
    compressed.type = ELFCOMPRESS_ZSTD;
    for (size_t i = 0; i != numShards; ++i)
      compressedSize += shardsOut[i].size();
  }
#endif

#if LLVM_ENABLE_ZLIB
  // We chose 1 (Z_BEST_SPEED) as the default compression level because it is
  // fast and provides decent compression ratios.
  if (ctype == DebugCompressionType::Zlib) {
    if (!level)
      level = Z_BEST_SPEED;

    // Compress shards and compute Alder-32 checksums. Use Z_SYNC_FLUSH for all
    // shards but the last to flush the output to a byte boundary to be
    // concatenated with the next shard.
    auto shardsAdler = std::make_unique<uint32_t[]>(numShards);
    parallelFor(0, numShards, [&](size_t i) {
      shardsOut[i] = deflateShard(ctx, shardsIn[i], level,
                                  i != numShards - 1 ? Z_SYNC_FLUSH : Z_FINISH);
      shardsAdler[i] = adler32(1, shardsIn[i].data(), shardsIn[i].size());
    });

    // Update section size and combine Alder-32 checksums.
    uint32_t checksum = 1;       // Initial Adler-32 value
    compressedSize += 2;         // Elf_Chdir and zlib header
    for (size_t i = 0; i != numShards; ++i) {
      compressedSize += shardsOut[i].size();
      checksum = adler32_combine(checksum, shardsAdler[i], shardsIn[i].size());
    }
    compressedSize += 4; // checksum
    compressed.type = ELFCOMPRESS_ZLIB;
    compressed.checksum = checksum;
  }
#endif

  if (compressedSize >= size)
    return;
  compressed.uncompressedSize = size;
  compressed.shards = std::move(shardsOut);
  compressed.numShards = numShards;
  size = compressedSize;
  flags |= SHF_COMPRESSED;
}

static void writeInt(Ctx &ctx, uint8_t *buf, uint64_t data, uint64_t size) {
  if (size == 1)
    *buf = data;
  else if (size == 2)
    write16(ctx, buf, data);
  else if (size == 4)
    write32(ctx, buf, data);
  else if (size == 8)
    write64(ctx, buf, data);
  else
    llvm_unreachable("unsupported Size argument");
}

template <class ELFT>
void OutputSection::writeTo(Ctx &ctx, uint8_t *buf, parallel::TaskGroup &tg) {
  llvm::TimeTraceScope timeScope("Write sections", name);
  if (type == SHT_NOBITS)
    return;
  if (type == SHT_CREL && !(flags & SHF_ALLOC)) {
    buf += encodeULEB128(crelHeader, buf);
    memcpy(buf, crelBody.data(), crelBody.size());
    return;
  }

  // If the section is compressed due to
  // --compress-debug-section/--compress-sections, the content is already known.
  if (compressed.shards) {
    auto *chdr = reinterpret_cast<typename ELFT::Chdr *>(buf);
    chdr->ch_type = compressed.type;
    chdr->ch_size = compressed.uncompressedSize;
    chdr->ch_addralign = addralign;
    buf += sizeof(*chdr);

    auto offsets = std::make_unique<size_t[]>(compressed.numShards);
    if (compressed.type == ELFCOMPRESS_ZLIB) {
      buf[0] = 0x78;  // CMF
      buf[1] = 0x01;  // FLG: best speed
      offsets[0] = 2; // zlib header
      write32be(buf + (size - sizeof(*chdr) - 4), compressed.checksum);
    }

    // Compute shard offsets.
    for (size_t i = 1; i != compressed.numShards; ++i)
      offsets[i] = offsets[i - 1] + compressed.shards[i - 1].size();
    parallelFor(0, compressed.numShards, [&](size_t i) {
      memcpy(buf + offsets[i], compressed.shards[i].data(),
             compressed.shards[i].size());
    });
    return;
  }

  // Write leading padding.
  ArrayRef<InputSection *> sections = getInputSections(*this, storage);
  std::array<uint8_t, 4> filler = getFiller(ctx);
  bool nonZeroFiller = read32(ctx, filler.data()) != 0;
  if (nonZeroFiller)
    fill(buf, sections.empty() ? size : sections[0]->outSecOff, filler);

  if (type == SHT_CREL && !(flags & SHF_ALLOC)) {
    buf += encodeULEB128(crelHeader, buf);
    memcpy(buf, crelBody.data(), crelBody.size());
    return;
  }

  auto fn = [=, &ctx](size_t begin, size_t end) {
    size_t numSections = sections.size();
    for (size_t i = begin; i != end; ++i) {
      InputSection *isec = sections[i];
      if (auto *s = dyn_cast<SyntheticSection>(isec))
        s->writeTo(buf + isec->outSecOff);
      else
        isec->writeTo<ELFT>(ctx, buf + isec->outSecOff);

      // When in Arm BE8 mode, the linker has to convert the big-endian
      // instructions to little-endian, leaving the data big-endian.
      if (ctx.arg.emachine == EM_ARM && !ctx.arg.isLE && ctx.arg.armBe8 &&
          (flags & SHF_EXECINSTR))
        convertArmInstructionstoBE8(ctx, isec, buf + isec->outSecOff);

      // Fill gaps between sections.
      if (nonZeroFiller) {
        uint8_t *start = buf + isec->outSecOff + isec->getSize();
        uint8_t *end;
        if (i + 1 == numSections)
          end = buf + size;
        else
          end = buf + sections[i + 1]->outSecOff;
        if (isec->nopFiller) {
          assert(ctx.target->nopInstrs);
          nopInstrFill(ctx, start, end - start);
        } else
          fill(start, end - start, filler);
      }
    }
  };

  // If there is any BYTE()-family command (rare), write the section content
  // first then process BYTE to overwrite the filler content. The write is
  // serial due to the limitation of llvm/Support/Parallel.h.
  bool written = false;
  size_t numSections = sections.size();
  for (SectionCommand *cmd : commands)
    if (auto *data = dyn_cast<ByteCommand>(cmd)) {
      if (!std::exchange(written, true))
        fn(0, numSections);
      writeInt(ctx, buf + data->offset, data->expression().getValue(),
               data->size);
    }
  if (written || !numSections)
    return;

  // There is no data command. Write content asynchronously to overlap the write
  // time with other output sections. Note, if a linker script specifies
  // overlapping output sections (needs --noinhibit-exec or --no-check-sections
  // to supress the error), the output may be non-deterministic.
  const size_t taskSizeLimit = 4 << 20;
  for (size_t begin = 0, i = 0, taskSize = 0;;) {
    taskSize += sections[i]->getSize();
    bool done = ++i == numSections;
    if (done || taskSize >= taskSizeLimit) {
      tg.spawn([=] { fn(begin, i); });
      if (done)
        break;
      begin = i;
      taskSize = 0;
    }
  }
}

static void finalizeShtGroup(Ctx &ctx, OutputSection *os,
                             InputSection *section) {
  // sh_link field for SHT_GROUP sections should contain the section index of
  // the symbol table.
  os->link = ctx.in.symTab->getParent()->sectionIndex;

  if (!section)
    return;

  // sh_info then contain index of an entry in symbol table section which
  // provides signature of the section group.
  ArrayRef<Symbol *> symbols = section->file->getSymbols();
  os->info = ctx.in.symTab->getSymbolIndex(*symbols[section->info]);

  // Some group members may be combined or discarded, so we need to compute the
  // new size. The content will be rewritten in InputSection::copyShtGroup.
  DenseSet<uint32_t> seen;
  ArrayRef<InputSectionBase *> sections = section->file->getSections();
  for (auto &idx : section->getDataAs<std::array<char, 4>>().slice(1))
    if (OutputSection *osec = sections[read32(ctx, &idx)]->getOutputSection())
      seen.insert(osec->sectionIndex);
  os->size = (1 + seen.size()) * sizeof(uint32_t);
}

template <class uint>
LLVM_ATTRIBUTE_ALWAYS_INLINE static void
encodeOneCrel(Ctx &ctx, raw_svector_ostream &os,
              Elf_Crel<sizeof(uint) == 8> &out, uint offset, const Symbol &sym,
              uint32_t type, uint addend) {
  const auto deltaOffset = static_cast<uint64_t>(offset - out.r_offset);
  out.r_offset = offset;
  int64_t symidx = ctx.in.symTab->getSymbolIndex(sym);
  if (sym.type == STT_SECTION) {
    auto *d = dyn_cast<Defined>(&sym);
    if (d) {
      SectionBase *section = d->section;
      assert(section->isLive());
      addend = sym.getVA(ctx, addend) - section->getOutputSection()->addr;
    } else {
      // Encode R_*_NONE(symidx=0).
      symidx = type = addend = 0;
    }
  }

  // Similar to llvm::ELF::encodeCrel.
  uint8_t b = deltaOffset * 8 + (out.r_symidx != symidx) +
              (out.r_type != type ? 2 : 0) +
              (uint(out.r_addend) != addend ? 4 : 0);
  if (deltaOffset < 0x10) {
    os << char(b);
  } else {
    os << char(b | 0x80);
    encodeULEB128(deltaOffset >> 4, os);
  }
  if (b & 1) {
    encodeSLEB128(static_cast<int32_t>(symidx - out.r_symidx), os);
    out.r_symidx = symidx;
  }
  if (b & 2) {
    encodeSLEB128(static_cast<int32_t>(type - out.r_type), os);
    out.r_type = type;
  }
  if (b & 4) {
    encodeSLEB128(std::make_signed_t<uint>(addend - out.r_addend), os);
    out.r_addend = addend;
  }
}

template <class ELFT>
static size_t relToCrel(Ctx &ctx, raw_svector_ostream &os,
                        Elf_Crel<ELFT::Is64Bits> &out, InputSection *relSec,
                        InputSectionBase *sec) {
  const auto &file = *cast<ELFFileBase>(relSec->file);
  if (relSec->type == SHT_REL) {
    // REL conversion is complex and unsupported yet.
    Err(ctx) << relSec << ": REL cannot be converted to CREL";
    return 0;
  }
  auto rels = relSec->getDataAs<typename ELFT::Rela>();
  for (auto rel : rels) {
    encodeOneCrel<typename ELFT::uint>(
        ctx, os, out, sec->getVA(rel.r_offset), file.getRelocTargetSym(rel),
        rel.getType(ctx.arg.isMips64EL), getAddend<ELFT>(rel));
  }
  return rels.size();
}

// Compute the content of a non-alloc CREL section due to -r or --emit-relocs.
// Input CREL sections are decoded while REL[A] need to be converted.
template <bool is64> void OutputSection::finalizeNonAllocCrel(Ctx &ctx) {
  using uint = typename Elf_Crel_Impl<is64>::uint;
  raw_svector_ostream os(crelBody);
  uint64_t totalCount = 0;
  Elf_Crel<is64> out{};
  assert(commands.size() == 1);
  auto *isd = cast<InputSectionDescription>(commands[0]);
  for (InputSection *relSec : isd->sections) {
    const auto &file = *cast<ELFFileBase>(relSec->file);
    InputSectionBase *sec = relSec->getRelocatedSection();
    if (relSec->type == SHT_CREL) {
      RelocsCrel<is64> entries(relSec->content_);
      totalCount += entries.size();
      for (Elf_Crel_Impl<is64> r : entries) {
        encodeOneCrel<uint>(ctx, os, out, uint(sec->getVA(r.r_offset)),
                            file.getSymbol(r.r_symidx), r.r_type, r.r_addend);
      }
      continue;
    }

    // Convert REL[A] to CREL.
    if constexpr (is64) {
      totalCount += ctx.arg.isLE
                        ? relToCrel<ELF64LE>(ctx, os, out, relSec, sec)
                        : relToCrel<ELF64BE>(ctx, os, out, relSec, sec);
    } else {
      totalCount += ctx.arg.isLE
                        ? relToCrel<ELF32LE>(ctx, os, out, relSec, sec)
                        : relToCrel<ELF32BE>(ctx, os, out, relSec, sec);
    }
  }

  crelHeader = totalCount * 8 + 4;
  size = getULEB128Size(crelHeader) + crelBody.size();
}

void OutputSection::finalize(Ctx &ctx) {
  InputSection *first = getFirstInputSection(this);

  if (flags & SHF_LINK_ORDER) {
    // We must preserve the link order dependency of sections with the
    // SHF_LINK_ORDER flag. The dependency is indicated by the sh_link field. We
    // need to translate the InputSection sh_link to the OutputSection sh_link,
    // all InputSections in the OutputSection have the same dependency.
    if (auto *ex = dyn_cast<ARMExidxSyntheticSection>(first))
      link = ex->getLinkOrderDep()->getParent()->sectionIndex;
    else if (first->flags & SHF_LINK_ORDER)
      if (auto *d = first->getLinkOrderDep())
        link = d->getParent()->sectionIndex;
  }

  if (type == SHT_GROUP) {
    finalizeShtGroup(ctx, this, first);
    return;
  }

  if (!ctx.arg.copyRelocs || !isStaticRelSecType(type))
    return;

  // Skip if 'first' is synthetic, i.e. not a section created by --emit-relocs.
  // Normally 'type' was changed by 'first' so 'first' should be non-null.
  // However, if the output section is .rela.dyn, 'type' can be set by the empty
  // synthetic .rela.plt and first can be null.
  if (!first || isa<SyntheticSection>(first))
    return;

  link = ctx.in.symTab->getParent()->sectionIndex;
  // sh_info for SHT_REL[A] sections should contain the section header index of
  // the section to which the relocation applies.
  InputSectionBase *s = first->getRelocatedSection();
  info = s->getOutputSection()->sectionIndex;
  flags |= SHF_INFO_LINK;
  // Finalize the content of non-alloc CREL.
  if (type == SHT_CREL) {
    if (ctx.arg.is64)
      finalizeNonAllocCrel<true>(ctx);
    else
      finalizeNonAllocCrel<false>(ctx);
  }
}

// Returns true if S is in one of the many forms the compiler driver may pass
// crtbegin files.
//
// Gcc uses any of crtbegin[<empty>|S|T].o.
// Clang uses Gcc's plus clang_rt.crtbegin[-<arch>|<empty>].o.

static bool isCrt(StringRef s, StringRef beginEnd) {
  s = sys::path::filename(s);
  if (!s.consume_back(".o"))
    return false;
  if (s.consume_front("clang_rt."))
    return s.consume_front(beginEnd);
  return s.consume_front(beginEnd) && s.size() <= 1;
}

// .ctors and .dtors are sorted by this order:
//
// 1. .ctors/.dtors in crtbegin (which contains a sentinel value -1).
// 2. The section is named ".ctors" or ".dtors" (priority: 65536).
// 3. The section has an optional priority value in the form of ".ctors.N" or
//    ".dtors.N" where N is a number in the form of %05u (priority: 65535-N).
// 4. .ctors/.dtors in crtend (which contains a sentinel value 0).
//
// For 2 and 3, the sections are sorted by priority from high to low, e.g.
// .ctors (65536), .ctors.00100 (65436), .ctors.00200 (65336).  In GNU ld's
// internal linker scripts, the sorting is by string comparison which can
// achieve the same goal given the optional priority values are of the same
// length.
//
// In an ideal world, we don't need this function because .init_array and
// .ctors are duplicate features (and .init_array is newer.) However, there
// are too many real-world use cases of .ctors, so we had no choice to
// support that with this rather ad-hoc semantics.
static bool compCtors(const InputSection *a, const InputSection *b) {
  bool beginA = isCrt(a->file->getName(), "crtbegin");
  bool beginB = isCrt(b->file->getName(), "crtbegin");
  if (beginA != beginB)
    return beginA;
  bool endA = isCrt(a->file->getName(), "crtend");
  bool endB = isCrt(b->file->getName(), "crtend");
  if (endA != endB)
    return endB;
  return getPriority(a->name) > getPriority(b->name);
}

// Sorts input sections by the special rules for .ctors and .dtors.
// Unfortunately, the rules are different from the one for .{init,fini}_array.
// Read the comment above.
void OutputSection::sortCtorsDtors() {
  assert(commands.size() == 1);
  auto *isd = cast<InputSectionDescription>(commands[0]);
  llvm::stable_sort(isd->sections, compCtors);
}

// If an input string is in the form of "foo.N" where N is a number, return N
// (65535-N if .ctors.N or .dtors.N). Otherwise, returns 65536, which is one
// greater than the lowest priority.
int elf::getPriority(StringRef s) {
  size_t pos = s.rfind('.');
  if (pos == StringRef::npos)
    return 65536;
  int v = 65536;
  if (to_integer(s.substr(pos + 1), v, 10) &&
      (pos == 6 && (s.starts_with(".ctors") || s.starts_with(".dtors"))))
    v = 65535 - v;
  return v;
}

InputSection *elf::getFirstInputSection(const OutputSection *os) {
  for (SectionCommand *cmd : os->commands)
    if (auto *isd = dyn_cast<InputSectionDescription>(cmd))
      if (!isd->sections.empty())
        return isd->sections[0];
  return nullptr;
}

ArrayRef<InputSection *>
elf::getInputSections(const OutputSection &os,
                      SmallVector<InputSection *, 0> &storage) {
  ArrayRef<InputSection *> ret;
  storage.clear();
  for (SectionCommand *cmd : os.commands) {
    auto *isd = dyn_cast<InputSectionDescription>(cmd);
    if (!isd)
      continue;
    if (ret.empty()) {
      ret = isd->sections;
    } else {
      if (storage.empty())
        storage.assign(ret.begin(), ret.end());
      storage.insert(storage.end(), isd->sections.begin(), isd->sections.end());
    }
  }
  return storage.empty() ? ret : ArrayRef(storage);
}

// Sorts input sections by section name suffixes, so that .foo.N comes
// before .foo.M if N < M. Used to sort .{init,fini}_array.N sections.
// We want to keep the original order if the priorities are the same
// because the compiler keeps the original initialization order in a
// translation unit and we need to respect that.
// For more detail, read the section of the GCC's manual about init_priority.
void OutputSection::sortInitFini() {
  // Sort sections by priority.
  sort([](InputSectionBase *s) { return getPriority(s->name); });
}

std::array<uint8_t, 4> OutputSection::getFiller(Ctx &ctx) {
  if (filler)
    return *filler;
  if (!(flags & SHF_EXECINSTR))
    return {0, 0, 0, 0};
  if (ctx.arg.relocatable && ctx.arg.emachine == EM_RISCV) {
    // See RISCV::maybeSynthesizeAlign: Synthesized NOP bytes and ALIGN
    // relocations might be needed between two input sections. Use a NOP for the
    // filler.
    if (ctx.arg.eflags & EF_RISCV_RVC)
      return {1, 0, 1, 0};
    return {0x13, 0, 0, 0};
  }
  if (ctx.arg.relocatable && ctx.arg.emachine == EM_LOONGARCH)
    return {0, 0, 0x40, 0x03};
  return ctx.target->trapInstr;
}

void OutputSection::checkDynRelAddends(Ctx &ctx) {
  assert(ctx.arg.writeAddends && ctx.arg.checkDynamicRelocs);
  assert(isStaticRelSecType(type));
  SmallVector<InputSection *, 0> storage;
  ArrayRef<InputSection *> sections = getInputSections(*this, storage);
  parallelFor(0, sections.size(), [&](size_t i) {
    // When linking with -r or --emit-relocs we might also call this function
    // for input .rel[a].<sec> sections which we simply pass through to the
    // output. We skip over those and only look at the synthetic relocation
    // sections created during linking.
    if (!SyntheticSection::classof(sections[i]) ||
        !is_contained({ELF::SHT_REL, ELF::SHT_RELA, ELF::SHT_RELR},
                      sections[i]->type))
      return;
    const auto *sec = cast<RelocationBaseSection>(sections[i]);
    if (!sec)
      return;
    for (const DynamicReloc &rel : sec->relocs) {
      int64_t addend = rel.addend;
      const OutputSection *relOsec = rel.inputSec->getOutputSection();
      assert(relOsec != nullptr && "missing output section for relocation");
      // Some targets have NOBITS synthetic sections with dynamic relocations
      // with non-zero addends. Skip such sections.
      if (is_contained({EM_PPC, EM_PPC64}, ctx.arg.emachine) &&
          (rel.inputSec == ctx.in.ppc64LongBranchTarget.get() ||
           rel.inputSec == ctx.in.igotPlt.get()))
        continue;
      const uint8_t *relocTarget = ctx.bufferStart + relOsec->offset +
                                   rel.inputSec->getOffset(rel.offsetInSec);
      // For SHT_NOBITS the written addend is always zero.
      int64_t writtenAddend =
          relOsec->type == SHT_NOBITS
              ? 0
              : ctx.target->getImplicitAddend(relocTarget, rel.type);
      if (addend != writtenAddend)
        InternalErr(ctx, relocTarget)
            << "wrote incorrect addend value 0x" << utohexstr(writtenAddend)
            << " instead of 0x" << utohexstr(addend)
            << " for dynamic relocation " << rel.type << " at offset 0x"
            << utohexstr(rel.getOffset())
            << (rel.sym ? " against symbol " + rel.sym->getName() : "");
    }
  });
}

template void OutputSection::writeHeaderTo<ELF32LE>(ELF32LE::Shdr *Shdr);
template void OutputSection::writeHeaderTo<ELF32BE>(ELF32BE::Shdr *Shdr);
template void OutputSection::writeHeaderTo<ELF64LE>(ELF64LE::Shdr *Shdr);
template void OutputSection::writeHeaderTo<ELF64BE>(ELF64BE::Shdr *Shdr);

template void OutputSection::writeTo<ELF32LE>(Ctx &, uint8_t *,
                                              llvm::parallel::TaskGroup &);
template void OutputSection::writeTo<ELF32BE>(Ctx &, uint8_t *,
                                              llvm::parallel::TaskGroup &);
template void OutputSection::writeTo<ELF64LE>(Ctx &, uint8_t *,
                                              llvm::parallel::TaskGroup &);
template void OutputSection::writeTo<ELF64BE>(Ctx &, uint8_t *,
                                              llvm::parallel::TaskGroup &);

template void OutputSection::maybeCompress<ELF32LE>(Ctx &);
template void OutputSection::maybeCompress<ELF32BE>(Ctx &);
template void OutputSection::maybeCompress<ELF64LE>(Ctx &);
template void OutputSection::maybeCompress<ELF64BE>(Ctx &);
