//===- Symbols.h ------------------------------------------------*- C++ -*-===//
//
//                             The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// All symbols are handled as SymbolBodies regardless of their types.
// This file defines various types of SymbolBodies.
//
// File-scope symbols in ELF objects are the only exception of SymbolBody
// instantiation. We will never create SymbolBodies for them for performance
// reason. They are often represented as nullptrs. This is fine for symbol
// resolution because the symbol table naturally cares only about
// externally-visible symbols. For relocations, you have to deal with both
// local and non-local functions, and we have two different functions
// where we need them.
//
//===----------------------------------------------------------------------===//

#ifndef LLD_ELF_SYMBOLS_H
#define LLD_ELF_SYMBOLS_H

#include "InputSection.h"

#include "lld/Core/LLVM.h"
#include "llvm/Object/Archive.h"
#include "llvm/Object/ELF.h"

namespace lld {
namespace elf2 {

class ArchiveFile;
class InputFile;
class SymbolBody;
template <class ELFT> class ObjectFile;
template <class ELFT> class OutputSection;
template <class ELFT> class OutputSectionBase;
template <class ELFT> class SharedFile;

// Initializes global objects defined in this file.
// Called at the beginning of main().
void initSymbols();

// A real symbol object, SymbolBody, is usually accessed indirectly
// through a Symbol. There's always one Symbol for each symbol name.
// The resolver updates SymbolBody pointers as it resolves symbols.
struct Symbol {
  SymbolBody *Body;
};

// The base class for real symbol classes.
class SymbolBody {
public:
  enum Kind {
    DefinedFirst,
    DefinedRegularKind = DefinedFirst,
    SharedKind,
    DefinedElfLast = SharedKind,
    DefinedCommonKind,
    DefinedSyntheticKind,
    DefinedLast = DefinedSyntheticKind,
    UndefinedElfKind,
    UndefinedKind,
    LazyKind
  };

  Kind kind() const { return static_cast<Kind>(SymbolKind); }

  bool isWeak() const { return IsWeak; }
  bool isUndefined() const {
    return SymbolKind == UndefinedKind || SymbolKind == UndefinedElfKind;
  }
  bool isDefined() const { return SymbolKind <= DefinedLast; }
  bool isCommon() const { return SymbolKind == DefinedCommonKind; }
  bool isLazy() const { return SymbolKind == LazyKind; }
  bool isShared() const { return SymbolKind == SharedKind; }
  bool isUsedInRegularObj() const { return IsUsedInRegularObj; }
  bool isUsedInDynamicReloc() const { return IsUsedInDynamicReloc; }
  void setUsedInDynamicReloc() { IsUsedInDynamicReloc = true; }
  bool isTls() const { return IsTls; }

  // Returns the symbol name.
  StringRef getName() const { return Name; }

  uint8_t getVisibility() const { return Visibility; }

  unsigned DynamicSymbolTableIndex = 0;
  uint32_t GlobalDynIndex = -1;
  uint32_t GotIndex = -1;
  uint32_t GotPltIndex = -1;
  uint32_t PltIndex = -1;
  bool hasGlobalDynIndex() { return GlobalDynIndex != uint32_t(-1); }
  bool isInGot() const { return GotIndex != -1U; }
  bool isInGotPlt() const { return GotPltIndex != -1U; }
  bool isInPlt() const { return PltIndex != -1U; }

  // A SymbolBody has a backreference to a Symbol. Originally they are
  // doubly-linked. A backreference will never change. But the pointer
  // in the Symbol may be mutated by the resolver. If you have a
  // pointer P to a SymbolBody and are not sure whether the resolver
  // has chosen the object among other objects having the same name,
  // you can access P->Backref->Body to get the resolver's result.
  void setBackref(Symbol *P) { Backref = P; }
  SymbolBody *repl() { return Backref ? Backref->Body : this; }
  Symbol *getSymbol() { return Backref; }

  // Decides which symbol should "win" in the symbol table, this or
  // the Other. Returns 1 if this wins, -1 if the Other wins, or 0 if
  // they are duplicate (conflicting) symbols.
  template <class ELFT> int compare(SymbolBody *Other);

protected:
  SymbolBody(Kind K, StringRef Name, bool IsWeak, uint8_t Visibility,
             bool IsTls)
      : SymbolKind(K), IsWeak(IsWeak), Visibility(Visibility), IsTls(IsTls),
        Name(Name) {
    IsUsedInRegularObj = K != SharedKind && K != LazyKind;
    IsUsedInDynamicReloc = 0;
  }

  const unsigned SymbolKind : 8;
  unsigned IsWeak : 1;
  unsigned Visibility : 2;

  // True if the symbol was used for linking and thus need to be
  // added to the output file's symbol table. It is usually true,
  // but if it is a shared symbol that were not referenced by anyone,
  // it can be false.
  unsigned IsUsedInRegularObj : 1;

  // If true, the symbol is added to .dynsym symbol table.
  unsigned IsUsedInDynamicReloc : 1;

  unsigned IsTls : 1;
  StringRef Name;
  Symbol *Backref = nullptr;
};

// The base class for any defined symbols.
class Defined : public SymbolBody {
public:
  Defined(Kind K, StringRef Name, bool IsWeak, uint8_t Visibility, bool IsTls);
  static bool classof(const SymbolBody *S) { return S->isDefined(); }
};

// Any defined symbol from an ELF file.
template <class ELFT> class DefinedElf : public Defined {
protected:
  typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym;

public:
  DefinedElf(Kind K, StringRef N, const Elf_Sym &Sym)
      : Defined(K, N, Sym.getBinding() == llvm::ELF::STB_WEAK,
                Sym.getVisibility(), Sym.getType() == llvm::ELF::STT_TLS),
        Sym(Sym) {}

  const Elf_Sym &Sym;
  static bool classof(const SymbolBody *S) {
    return S->kind() <= DefinedElfLast;
  }
};

class DefinedCommon : public Defined {
public:
  DefinedCommon(StringRef N, uint64_t Size, uint64_t Alignment, bool IsWeak,
                uint8_t Visibility);

  static bool classof(const SymbolBody *S) {
    return S->kind() == SymbolBody::DefinedCommonKind;
  }

  // The output offset of this common symbol in the output bss. Computed by the
  // writer.
  uint64_t OffsetInBss;

  // The maximum alignment we have seen for this symbol.
  uint64_t MaxAlignment;

  uint64_t Size;
};

// Regular defined symbols read from object file symbol tables.
template <class ELFT> class DefinedRegular : public DefinedElf<ELFT> {
  typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym;

public:
  DefinedRegular(StringRef N, const Elf_Sym &Sym,
                 InputSectionBase<ELFT> *Section)
      : DefinedElf<ELFT>(SymbolBody::DefinedRegularKind, N, Sym),
        Section(Section) {}

  static bool classof(const SymbolBody *S) {
    return S->kind() == SymbolBody::DefinedRegularKind;
  }

  // If this is null, the symbol is absolute.
  InputSectionBase<ELFT> *Section;
};

// DefinedSynthetic is a class to represent linker-generated ELF symbols.
// The difference from the regular symbol is that DefinedSynthetic symbols
// don't belong to any input files or sections. Thus, its constructor
// takes an output section to calculate output VA, etc.
template <class ELFT> class DefinedSynthetic : public Defined {
public:
  typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym;
  typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t;
  DefinedSynthetic(StringRef N, uintX_t Value,
                   OutputSectionBase<ELFT> &Section);

  static bool classof(const SymbolBody *S) {
    return S->kind() == SymbolBody::DefinedSyntheticKind;
  }

  uintX_t Value;
  const OutputSectionBase<ELFT> &Section;
};

// Undefined symbol.
class Undefined : public SymbolBody {
  typedef SymbolBody::Kind Kind;
  bool CanKeepUndefined;

protected:
  Undefined(Kind K, StringRef N, bool IsWeak, uint8_t Visibility, bool IsTls);

public:
  Undefined(StringRef N, bool IsWeak, uint8_t Visibility,
            bool CanKeepUndefined);

  static bool classof(const SymbolBody *S) { return S->isUndefined(); }

  bool canKeepUndefined() const { return CanKeepUndefined; }
};

template <class ELFT> class UndefinedElf : public Undefined {
  typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym;

public:
  UndefinedElf(StringRef N, const Elf_Sym &Sym);
  const Elf_Sym &Sym;

  static bool classof(const SymbolBody *S) {
    return S->kind() == SymbolBody::UndefinedElfKind;
  }
};

template <class ELFT> class SharedSymbol : public DefinedElf<ELFT> {
  typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym;
  typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t;

public:
  static bool classof(const SymbolBody *S) {
    return S->kind() == SymbolBody::SharedKind;
  }

  SharedSymbol(SharedFile<ELFT> *F, StringRef Name, const Elf_Sym &Sym)
      : DefinedElf<ELFT>(SymbolBody::SharedKind, Name, Sym), File(F) {}

  SharedFile<ELFT> *File;

  // True if the linker has to generate a copy relocation for this shared
  // symbol. OffsetInBss is significant only when NeedsCopy is true.
  bool NeedsCopy = false;
  uintX_t OffsetInBss = 0;
};

// This class represents a symbol defined in an archive file. It is
// created from an archive file header, and it knows how to load an
// object file from an archive to replace itself with a defined
// symbol. If the resolver finds both Undefined and Lazy for
// the same name, it will ask the Lazy to load a file.
class Lazy : public SymbolBody {
public:
  Lazy(ArchiveFile *F, const llvm::object::Archive::Symbol S)
      : SymbolBody(LazyKind, S.getName(), false, llvm::ELF::STV_DEFAULT, false),
        File(F), Sym(S) {}

  static bool classof(const SymbolBody *S) { return S->kind() == LazyKind; }

  // Returns an object file for this symbol, or a nullptr if the file
  // was already returned.
  std::unique_ptr<InputFile> getMember();

  void setWeak() { IsWeak = true; }
  void setUsedInRegularObj() { IsUsedInRegularObj = true; }

private:
  ArchiveFile *File;
  const llvm::object::Archive::Symbol Sym;
};

// Some linker-generated symbols need to be created as
// DefinedRegular symbols, so they need Elf_Sym symbols.
// Here we allocate such Elf_Sym symbols statically.
template <class ELFT> struct ElfSym {
  typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym;

  // Used to represent an undefined symbol which we don't want
  // to add to the output file's symbol table. The `IgnoredWeak`
  // has weak binding and can be substituted. The `Ignore` has
  // global binding and gets priority over symbols from shared libs.
  static Elf_Sym IgnoredWeak;
  static Elf_Sym Ignored;

  // The content for _end and end symbols.
  static Elf_Sym End;

  // The content for _gp symbol for MIPS target.
  static Elf_Sym MipsGp;

  // __rel_iplt_start/__rel_iplt_end for signaling
  // where R_[*]_IRELATIVE relocations do live.
  static Elf_Sym RelaIpltStart;
  static Elf_Sym RelaIpltEnd;
};

template <class ELFT> typename ElfSym<ELFT>::Elf_Sym ElfSym<ELFT>::IgnoredWeak;
template <class ELFT> typename ElfSym<ELFT>::Elf_Sym ElfSym<ELFT>::Ignored;
template <class ELFT> typename ElfSym<ELFT>::Elf_Sym ElfSym<ELFT>::End;
template <class ELFT> typename ElfSym<ELFT>::Elf_Sym ElfSym<ELFT>::MipsGp;
template <class ELFT>
typename ElfSym<ELFT>::Elf_Sym ElfSym<ELFT>::RelaIpltStart;
template <class ELFT> typename ElfSym<ELFT>::Elf_Sym ElfSym<ELFT>::RelaIpltEnd;

} // namespace elf2
} // namespace lld

#endif
