//===- 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 "Thunks.h"
#include "lld/Common/LLVM.h"
#include "llvm/ADT/CachedHashString.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/TinyPtrVector.h"
#include "llvm/Object/ELF.h"

namespace lld {
namespace elf {

class Symbol;
struct SectionPiece;

class Defined;
class SyntheticSection;
class MergeSyntheticSection;
template <class ELFT> class ObjFile;
class OutputSection;

// 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 { Regular, EHFrame, Merge, Synthetic, Output };

  Kind kind() const { return (Kind)SectionKind; }

  StringRef Name;

  // This pointer points to the "real" instance of this instance.
  // Usually Repl == this. However, if ICF merges two sections,
  // Repl pointer of one section points to another section. So,
  // if you need to get a pointer to this instance, do not use
  // this but instead this->Repl.
  SectionBase *Repl;

  unsigned SectionKind : 3;

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

  // The garbage collector sets sections' Live bits.
  // If GC is disabled, all sections are considered live by default.
  unsigned Live : 1;

  // True if this section has already been placed to a linker script
  // output section. This is needed because, in a linker script, you
  // can refer to the same section more than once. For example, in
  // the following linker script,
  //
  //   .foo : { *(.text) }
  //   .bar : { *(.text) }
  //
  // .foo takes all .text sections, and .bar becomes empty. To achieve
  // this, we need to memorize whether a section has been placed or
  // not for each input section.
  unsigned Assigned : 1;

  unsigned Bss : 1;

  // Set for sections that should not be folded by ICF.
  unsigned KeepUnique : 1;

  // These corresponds to the fields in Elf_Shdr.
  uint32_t Alignment;
  uint64_t Flags;
  uint64_t Entsize;
  uint32_t Type;
  uint32_t Link;
  uint32_t Info;

  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;

protected:
  SectionBase(Kind SectionKind, StringRef Name, uint64_t Flags,
              uint64_t Entsize, uint64_t Alignment, uint32_t Type,
              uint32_t Info, uint32_t Link)
      : Name(Name), Repl(this), SectionKind(SectionKind), Live(false),
        Assigned(false), Bss(false), KeepUnique(false), Alignment(Alignment),
        Flags(Flags), Entsize(Entsize), Type(Type), Link(Link), Info(Info) {}
};

// This corresponds to a section of an input file.
class InputSectionBase : public SectionBase {
public:
  template <class ELFT>
  InputSectionBase(ObjFile<ELFT> &File, const typename ELFT::Shdr &Header,
                   StringRef Name, Kind SectionKind);

  InputSectionBase(InputFile *File, uint64_t Flags, uint32_t Type,
                   uint64_t Entsize, uint32_t Link, uint32_t Info,
                   uint32_t Alignment, ArrayRef<uint8_t> Data, StringRef Name,
                   Kind SectionKind);

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

  // Relocations that refer to this section.
  unsigned NumRelocations : 31;
  unsigned AreRelocsRela : 1;
  const void *FirstRelocation = nullptr;

  // The file which contains this section. Its dynamic type is always
  // ObjFile<ELFT>, but in order to avoid ELFT, we use InputFile as
  // its static type.
  InputFile *File;

  template <class ELFT> ObjFile<ELFT> *getFile() const {
    return cast_or_null<ObjFile<ELFT>>(File);
  }

  ArrayRef<uint8_t> data() const {
    if (UncompressedSize >= 0)
      uncompress();
    return RawData;
  }

  uint64_t getOffsetInFile() const;

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

  template <class ELFT> ArrayRef<typename ELFT::Rel> rels() const {
    assert(!AreRelocsRela);
    return llvm::makeArrayRef(
        static_cast<const typename ELFT::Rel *>(FirstRelocation),
        NumRelocations);
  }

  template <class ELFT> ArrayRef<typename ELFT::Rela> relas() const {
    assert(AreRelocsRela);
    return llvm::makeArrayRef(
        static_cast<const typename ELFT::Rela *>(FirstRelocation),
        NumRelocations);
  }

  // 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 the function symbol that encloses this offset from within the
  // section.
  template <class ELFT>
  Defined *getEnclosingFunction(uint64_t Offset);

  // Returns a source location string. Used to construct an error message.
  template <class ELFT> std::string getLocation(uint64_t Offset);
  std::string getSrcMsg(const Symbol &Sym, uint64_t Offset);
  std::string getObjMsg(uint64_t Offset);

  // 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> void relocate(uint8_t *Buf, uint8_t *BufEnd);
  void relocateAlloc(uint8_t *Buf, uint8_t *BufEnd);

  // 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.
  std::vector<Relocation> Relocations;

  // 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(uint8_t *Buf, uint8_t *End);


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

protected:
  void parseCompressedHeader();
  void uncompress() const;

  mutable ArrayRef<uint8_t> RawData;

  // This field stores the uncompressed size of the compressed data in RawData,
  // or -1 if RawData is not compressed (either because the section wasn't
  // compressed in the first place, or because we ended up uncompressing it).
  // Since the feature is not used often, this is usually -1.
  mutable int64_t UncompressedSize = -1;
};

// 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(size_t Off, uint32_t Hash, bool Live)
      : InputOff(Off), Hash(Hash), OutputOff(0),
        Live(Live || !Config->GcSections) {}

  uint32_t InputOff;
  uint32_t Hash;
  int64_t OutputOff : 63;
  uint64_t Live : 1;
};

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

// 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(uint64_t Flags, uint32_t Type, uint64_t Entsize,
                    ArrayRef<uint8_t> Data, StringRef Name);

  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.
  uint64_t getParentOffset(uint64_t Offset) const;

  // Splittable sections are handled as a sequence of data
  // rather than a single large blob of data.
  std::vector<SectionPiece> 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) ? data().size() : Pieces[I + 1].InputOff;
    return {toStringRef(data().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;

private:
  void splitStrings(ArrayRef<uint8_t> A, 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() {
    return {Sec->data().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 split(ArrayRef<RelTy> Rels);

  // Splittable sections are handled as a sequence of data
  // rather than a single large blob of data.
  std::vector<EhSectionPiece> Pieces;

  SyntheticSection *getParent() const;
};

// 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, uint64_t Flags, uint32_t Type, uint32_t Alignment,
               ArrayRef<uint8_t> Data, StringRef Name, Kind K = Regular);
  template <class ELFT>
  InputSection(ObjFile<ELFT> &F, const typename ELFT::Shdr &Header,
               StringRef Name);

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

  uint64_t getOffset(uint64_t Offset) const { return OutSecOff + Offset; }

  OutputSection *getParent() const;

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

  static bool classof(const SectionBase *S);

  InputSectionBase *getRelocatedSection() const;

  template <class ELFT, class RelTy>
  void relocateNonAlloc(uint8_t *Buf, llvm::ArrayRef<RelTy> Rels);

  // Used by ICF.
  uint32_t Class[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(uint8_t *Buf, llvm::ArrayRef<RelTy> Rels);

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

// The list of all input sections.
extern std::vector<InputSectionBase *> InputSections;

} // namespace elf

std::string toString(const elf::InputSectionBase *);
} // namespace lld

#endif
