//===- InputSection.h -------------------------------------------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//

#ifndef LLD_ELF_INPUT_SECTION_H
#define LLD_ELF_INPUT_SECTION_H

#include "Config.h"
#include "Relocations.h"
#include "lld/Common/CommonLinkerContext.h"
#include "lld/Common/LLVM.h"
#include "lld/Common/Memory.h"
#include "llvm/ADT/CachedHashString.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/TinyPtrVector.h"
#include "llvm/Object/ELF.h"
#include "llvm/Support/Compiler.h"

namespace lld {
namespace elf {

class InputFile;
class Symbol;

class Defined;
struct Partition;
class SyntheticSection;
template <class ELFT> class ObjFile;
class OutputSection;

// Returned by InputSectionBase::relsOrRelas. At least two members are empty.
template <class ELFT> struct RelsOrRelas {
  Relocs<typename ELFT::Rel> rels;
  Relocs<typename ELFT::Rela> relas;
  Relocs<typename ELFT::Crel> crels;
  bool areRelocsRel() const { return rels.size(); }
  bool areRelocsCrel() const { return crels.size(); }
};

#define invokeOnRelocs(sec, f, ...)                                            \
  {                                                                            \
    const RelsOrRelas<ELFT> rs = (sec).template relsOrRelas<ELFT>();           \
    if (rs.areRelocsCrel())                                                    \
      f(__VA_ARGS__, rs.crels);                                                \
    else if (rs.areRelocsRel())                                                \
      f(__VA_ARGS__, rs.rels);                                                 \
    else                                                                       \
      f(__VA_ARGS__, rs.relas);                                                \
  }

// This is the base class of all sections that lld handles. Some are sections in
// input files, some are sections in the produced output file and some exist
// just as a convenience for implementing special ways of combining some
// sections.
class SectionBase {
public:
  enum Kind : uint8_t {
    Regular,
    Synthetic,
    Spill,
    EHFrame,
    Merge,
    Output,
    Class,
  };

  Kind kind() const { return sectionKind; }

  // The file which contains this section. For InputSectionBase, its dynamic
  // type is usually ObjFile<ELFT>, but may be an InputFile of InternalKind
  // (for a synthetic section).
  InputFile *file;

  StringRef name;

  // The 1-indexed partition that this section is assigned to by the garbage
  // collector, or 0 if this section is dead. Normally there is only one
  // partition, so this will either be 0 or 1.
  elf::Partition &getPartition(Ctx &) const;

  // These corresponds to the fields in Elf_Shdr.
  uint64_t flags;
  uint32_t type;
  uint32_t link;
  uint32_t info;
  uint32_t addralign;
  uint32_t entsize;

  Kind sectionKind;
  uint8_t partition = 1;

  // The next two bit fields are only used by InputSectionBase, but we
  // put them here so the struct packs better.

  Ctx &getCtx() const;
  OutputSection *getOutputSection();
  const OutputSection *getOutputSection() const {
    return const_cast<SectionBase *>(this)->getOutputSection();
  }

  // Translate an offset in the input section to an offset in the output
  // section.
  uint64_t getOffset(uint64_t offset) const;

  uint64_t getVA(uint64_t offset = 0) const;

  bool isLive() const { return partition != 0; }
  void markLive() { partition = 1; }
  void markDead() { partition = 0; }

protected:
  constexpr SectionBase(Kind sectionKind, InputFile *file, StringRef name,
                        uint32_t type, uint64_t flags, uint32_t link,
                        uint32_t info, uint32_t addralign, uint32_t entsize)
      : file(file), name(name), flags(flags), type(type), link(link),
        info(info), addralign(addralign), entsize(entsize),
        sectionKind(sectionKind) {}
};

struct SymbolAnchor {
  uint64_t offset;
  Defined *d;
  bool end; // true for the anchor of st_value+st_size
};

struct RelaxAux {
  // This records symbol start and end offsets which will be adjusted according
  // to the nearest relocDeltas element.
  SmallVector<SymbolAnchor, 0> anchors;
  // For relocations[i], the actual offset is
  //   r_offset - (i ? relocDeltas[i-1] : 0).
  std::unique_ptr<uint32_t[]> relocDeltas;
  // For relocations[i], the actual type is relocTypes[i].
  std::unique_ptr<RelType[]> relocTypes;
  SmallVector<uint32_t, 0> writes;
};

// This corresponds to a section of an input file.
class InputSectionBase : public SectionBase {
public:
  struct ObjMsg {
    const InputSectionBase *sec;
    uint64_t offset;
  };
  struct SrcMsg {
    const InputSectionBase &sec;
    const Symbol &sym;
    uint64_t offset;
  };

  template <class ELFT>
  InputSectionBase(ObjFile<ELFT> &file, const typename ELFT::Shdr &header,
                   StringRef name, Kind sectionKind);

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

  static bool classof(const SectionBase *s) {
    return s->kind() != Output && s->kind() != Class;
  }

  LLVM_PREFERRED_TYPE(bool)
  uint8_t bss : 1;

  // Whether this section is SHT_CREL and has been decoded to RELA by
  // relsOrRelas.
  LLVM_PREFERRED_TYPE(bool)
  uint8_t decodedCrel : 1;

  // Set for sections that should not be folded by ICF.
  LLVM_PREFERRED_TYPE(bool)
  uint8_t keepUnique : 1;

  // Whether the section needs to be padded with a NOP filler due to
  // deleteFallThruJmpInsn.
  LLVM_PREFERRED_TYPE(bool)
  uint8_t nopFiller : 1;

  mutable bool compressed = false;

  // Input sections are part of an output section. Special sections
  // like .eh_frame and merge sections are first combined into a
  // synthetic section that is then added to an output section. In all
  // cases this points one level up.
  SectionBase *parent = nullptr;

  // Section index of the relocation section if exists.
  uint32_t relSecIdx = 0;

  // Getter when the dynamic type is ObjFile<ELFT>.
  template <class ELFT> ObjFile<ELFT> *getFile() const {
    return cast<ObjFile<ELFT>>(file);
  }

  // Used by --optimize-bb-jumps and RISC-V linker relaxation temporarily to
  // indicate the number of bytes which is not counted in the size. This should
  // be reset to zero after uses.
  uint32_t bytesDropped = 0;

  void drop_back(unsigned num) {
    assert(bytesDropped + num < 256);
    bytesDropped += num;
  }

  void push_back(uint64_t num) {
    assert(bytesDropped >= num);
    bytesDropped -= num;
  }

  mutable const uint8_t *content_;
  uint64_t size;

  void trim() {
    if (bytesDropped) {
      size -= bytesDropped;
      bytesDropped = 0;
    }
  }

  ArrayRef<uint8_t> content() const {
    return ArrayRef<uint8_t>(content_, size);
  }
  ArrayRef<uint8_t> contentMaybeDecompress() const {
    if (compressed)
      decompress();
    return content();
  }

  // The next member in the section group if this section is in a group. This is
  // used by --gc-sections.
  InputSectionBase *nextInSectionGroup = nullptr;

  template <class ELFT>
  RelsOrRelas<ELFT> relsOrRelas(bool supportsCrel = true) const;

  // InputSections that are dependent on us (reverse dependency for GC)
  llvm::TinyPtrVector<InputSection *> dependentSections;

  // Returns the size of this section (even if this is a common or BSS.)
  size_t getSize() const;

  InputSection *getLinkOrderDep() const;

  // Get a symbol that encloses this offset from within the section. If type is
  // not zero, return a symbol with the specified type.
  Defined *getEnclosingSymbol(uint64_t offset, uint8_t type = 0) const;
  Defined *getEnclosingFunction(uint64_t offset) const {
    return getEnclosingSymbol(offset, llvm::ELF::STT_FUNC);
  }

  // Returns a source location string. Used to construct an error message.
  std::string getLocation(uint64_t offset) const;
  ObjMsg getObjMsg(uint64_t offset) const { return {this, offset}; }
  SrcMsg getSrcMsg(const Symbol &sym, uint64_t offset) const {
    return {*this, sym, offset};
  }

  uint64_t getRelocTargetVA(Ctx &, const Relocation &r, uint64_t p) const;

  // The native ELF reloc data type is not very convenient to handle.
  // So we convert ELF reloc records to our own records in Relocations.cpp.
  // This vector contains such "cooked" relocations.
  SmallVector<Relocation, 0> relocations;

  void addReloc(const Relocation &r) { relocations.push_back(r); }
  MutableArrayRef<Relocation> relocs() { return relocations; }
  ArrayRef<Relocation> relocs() const { return relocations; }

  union {
    // These are modifiers to jump instructions that are necessary when basic
    // block sections are enabled.  Basic block sections creates opportunities
    // to relax jump instructions at basic block boundaries after reordering the
    // basic blocks.
    JumpInstrMod *jumpInstrMod = nullptr;

    // Auxiliary information for RISC-V and LoongArch linker relaxation.
    // They do not use jumpInstrMod.
    RelaxAux *relaxAux;

    // The compressed content size when `compressed` is true.
    size_t compressedSize;
  };

  // A function compiled with -fsplit-stack calling a function
  // compiled without -fsplit-stack needs its prologue adjusted. Find
  // such functions and adjust their prologues.  This is very similar
  // to relocation. See https://gcc.gnu.org/wiki/SplitStacks for more
  // information.
  template <typename ELFT>
  void adjustSplitStackFunctionPrologues(Ctx &, uint8_t *buf, uint8_t *end);

  template <typename T> llvm::ArrayRef<T> getDataAs() const {
    size_t s = content().size();
    assert(s % sizeof(T) == 0);
    assert(reinterpret_cast<uintptr_t>(content().data()) % alignof(T) == 0);
    return llvm::ArrayRef<T>((const T *)content().data(), s / sizeof(T));
  }

protected:
  template <typename ELFT> void parseCompressedHeader(Ctx &);
  void decompress() const;
};

// SectionPiece represents a piece of splittable section contents.
// We allocate a lot of these and binary search on them. This means that they
// have to be as compact as possible, which is why we don't store the size (can
// be found by looking at the next one).
struct SectionPiece {
  SectionPiece() = default;
  SectionPiece(size_t off, uint32_t hash, bool live)
      : inputOff(off), live(live), hash(hash >> 1) {}

  uint32_t inputOff;
  LLVM_PREFERRED_TYPE(bool)
  uint32_t live : 1;
  uint32_t hash : 31;
  uint64_t outputOff = 0;
};

static_assert(sizeof(SectionPiece) == 16, "SectionPiece is too big");

// Used by splitSections to pre-resolve section piece indexes. 32 bits of offset
// supports section piece up to 4GB.
constexpr unsigned mergeValueShift = 32;

// This corresponds to a SHF_MERGE section of an input file.
class MergeInputSection : public InputSectionBase {
public:
  template <class ELFT>
  MergeInputSection(ObjFile<ELFT> &f, const typename ELFT::Shdr &header,
                    StringRef name);
  MergeInputSection(Ctx &, StringRef name, uint32_t type, uint64_t flags,
                    uint64_t entsize, ArrayRef<uint8_t> data);

  static bool classof(const SectionBase *s) { return s->kind() == Merge; }
  void splitIntoPieces();

  // Translate an offset in the input section to an offset in the parent
  // MergeSyntheticSection. If the offset was pre-resolved by
  // resolveSymbolPieces (upper bits non-zero), this is O(1).
  uint64_t getParentOffset(uint64_t offset) const;

  // Splittable sections are handled as a sequence of data
  // rather than a single large blob of data.
  SmallVector<SectionPiece, 0> pieces;

  // Returns I'th piece's data. This function is very hot when
  // string merging is enabled, so we want to inline.
  LLVM_ATTRIBUTE_ALWAYS_INLINE
  llvm::CachedHashStringRef getData(size_t i) const {
    size_t begin = pieces[i].inputOff;
    size_t end =
        (pieces.size() - 1 == i) ? content().size() : pieces[i + 1].inputOff;
    return {toStringRef(content().slice(begin, end - begin)), pieces[i].hash};
  }

  // Returns the SectionPiece at a given input section offset.
  SectionPiece &getSectionPiece(uint64_t offset);
  const SectionPiece &getSectionPiece(uint64_t offset) const {
    return const_cast<MergeInputSection *>(this)->getSectionPiece(offset);
  }

  SyntheticSection *getParent() const {
    return cast_or_null<SyntheticSection>(parent);
  }

private:
  void splitStrings(StringRef s, size_t size);
  void splitNonStrings(ArrayRef<uint8_t> a, size_t size);
};

struct EhSectionPiece {
  EhSectionPiece(size_t off, InputSectionBase *sec, uint32_t size,
                 unsigned firstRelocation)
      : inputOff(off), sec(sec), size(size), firstRelocation(firstRelocation) {}

  ArrayRef<uint8_t> data() const {
    return {sec->content().data() + this->inputOff, size};
  }

  size_t inputOff;
  ssize_t outputOff = -1;
  InputSectionBase *sec;
  uint32_t size;
  unsigned firstRelocation;
};

// This corresponds to a .eh_frame section of an input file.
class EhInputSection : public InputSectionBase {
public:
  template <class ELFT>
  EhInputSection(ObjFile<ELFT> &f, const typename ELFT::Shdr &header,
                 StringRef name);
  static bool classof(const SectionBase *s) { return s->kind() == EHFrame; }
  template <class ELFT> void split();
  template <class ELFT, class RelTy> void preprocessRelocs(Relocs<RelTy> rels);

  // Splittable sections are handled as a sequence of data
  // rather than a single large blob of data.
  SmallVector<EhSectionPiece, 0> cies, fdes;

  SyntheticSection *getParent() const;
  uint64_t getParentOffset(uint64_t offset) const;

  // Preprocessed relocations in uniform format to avoid REL/RELA/CREL
  // relocation format handling throughout the codebase.
  SmallVector<Relocation, 0> rels;
};

// This is a section that is added directly to an output section
// instead of needing special combination via a synthetic section. This
// includes all input sections with the exceptions of SHF_MERGE and
// .eh_frame. It also includes the synthetic sections themselves.
class InputSection : public InputSectionBase {
public:
  InputSection(InputFile *f, StringRef name, uint32_t type, uint64_t flags,
               uint32_t addralign, uint32_t entsize, ArrayRef<uint8_t> data,
               Kind k = Regular);
  template <class ELFT>
  InputSection(ObjFile<ELFT> &f, const typename ELFT::Shdr &header,
               StringRef name);

  static bool classof(const SectionBase *s) {
    return s->kind() == SectionBase::Regular ||
           s->kind() == SectionBase::Synthetic ||
           s->kind() == SectionBase::Spill;
  }

  // Write this section to a mmap'ed file, assuming Buf is pointing to
  // beginning of the output section.
  template <class ELFT> void writeTo(Ctx &, uint8_t *buf);

  OutputSection *getParent() const {
    return reinterpret_cast<OutputSection *>(parent);
  }

  // This variable has two usages. Initially, it represents an index in the
  // OutputSection's InputSection list, and is used when ordering SHF_LINK_ORDER
  // sections. After assignAddresses is called, it represents the offset from
  // the beginning of the output section this section was assigned to.
  uint64_t outSecOff = 0;

  InputSectionBase *getRelocatedSection() const;

  // Each section knows how to relocate itself. These functions apply
  // relocations, assuming that `buf` points to this section's copy in
  // the mmap'ed output buffer.
  template <class ELFT, class RelTy>
  void relocateNonAlloc(Ctx &, uint8_t *buf, Relocs<RelTy> rels);
  template <class ELFT> void relocate(Ctx &, uint8_t *buf, uint8_t *bufEnd);

  // Points to the canonical section. If ICF folds two sections, repl pointer of
  // one section points to the other.
  InputSection *repl = this;

  // Used by ICF.
  uint32_t eqClass[2] = {0, 0};

  // Called by ICF to merge two input sections.
  void replace(InputSection *other);

  static InputSection discarded;

private:
  template <class ELFT, class RelTy> void copyRelocations(Ctx &, uint8_t *buf);

  template <class ELFT, class RelTy, class RelIt>
  void copyRelocations(Ctx &, uint8_t *buf, llvm::iterator_range<RelIt> rels);

  template <class ELFT> void copyShtGroup(uint8_t *buf);
};

// A marker for a potential spill location for another input section. This
// broadly acts as if it were the original section until address assignment.
// Then it is either replaced with the real input section or removed.
class PotentialSpillSection : public InputSection {
public:
  // The containing input section description; used to quickly replace this stub
  // with the actual section.
  InputSectionDescription *isd;

  // Next potential spill location for the same source input section.
  PotentialSpillSection *next = nullptr;

  PotentialSpillSection(const InputSectionBase &source,
                        InputSectionDescription &isd);

  static bool classof(const SectionBase *sec) {
    return sec->kind() == InputSectionBase::Spill;
  }
};

#ifndef _WIN32
static_assert(sizeof(InputSection) <= 152, "InputSection is too big");
#endif

class SyntheticSection : public InputSection {
public:
  Ctx &ctx;
  SyntheticSection(Ctx &ctx, StringRef name, uint32_t type, uint64_t flags,
                   uint32_t addralign)
      : InputSection(ctx.internalFile, name, type, flags, addralign,
                     /*entsize=*/0, {}, InputSectionBase::Synthetic),
        ctx(ctx) {}

  virtual ~SyntheticSection() = default;
  virtual size_t getSize() const = 0;
  virtual bool updateAllocSize(Ctx &) { return false; }
  // If the section has the SHF_ALLOC flag and the size may be changed if
  // thunks are added, update the section size.
  virtual bool isNeeded() const { return true; }
  virtual void finalizeContents() {}
  virtual void writeTo(uint8_t *buf) = 0;

  static bool classof(const SectionBase *sec) {
    return sec->kind() == InputSectionBase::Synthetic;
  }
};

inline bool isStaticRelSecType(uint32_t type) {
  return type == llvm::ELF::SHT_RELA || type == llvm::ELF::SHT_CREL ||
         type == llvm::ELF::SHT_REL;
}

inline bool isDebugSection(const InputSectionBase &sec) {
  return (sec.flags & llvm::ELF::SHF_ALLOC) == 0 &&
         sec.name.starts_with(".debug");
}

std::string toStr(elf::Ctx &, const elf::InputSectionBase *);
const ELFSyncStream &operator<<(const ELFSyncStream &,
                                const InputSectionBase *);
const ELFSyncStream &operator<<(const ELFSyncStream &,
                                InputSectionBase::ObjMsg &&);
const ELFSyncStream &operator<<(const ELFSyncStream &,
                                InputSectionBase::SrcMsg &&);
} // namespace elf
} // namespace lld

#endif
