//===- ELFTypes.h - Endian specific types for ELF ---------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_OBJECT_ELF_TYPES_H
#define LLVM_OBJECT_ELF_TYPES_H

#include "llvm/Support/AlignOf.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ELF.h"
#include "llvm/Support/Endian.h"

namespace llvm {
namespace object {

using support::endianness;

template <endianness target_endianness, std::size_t max_alignment,
          bool is64Bits>
struct ELFType {
  static const endianness TargetEndianness = target_endianness;
  static const std::size_t MaxAlignment = max_alignment;
  static const bool Is64Bits = is64Bits;
};

template <typename T, int max_align> struct MaximumAlignment {
  enum { value = AlignOf<T>::Alignment > max_align ? max_align
                                                   : AlignOf<T>::Alignment
  };
};

// Templates to choose Elf_Addr and Elf_Off depending on is64Bits.
template <endianness target_endianness, std::size_t max_alignment>
struct ELFDataTypeTypedefHelperCommon {
  typedef support::detail::packed_endian_specific_integral<
      uint16_t, target_endianness,
      MaximumAlignment<uint16_t, max_alignment>::value> Elf_Half;
  typedef support::detail::packed_endian_specific_integral<
      uint32_t, target_endianness,
      MaximumAlignment<uint32_t, max_alignment>::value> Elf_Word;
  typedef support::detail::packed_endian_specific_integral<
      int32_t, target_endianness,
      MaximumAlignment<int32_t, max_alignment>::value> Elf_Sword;
  typedef support::detail::packed_endian_specific_integral<
      uint64_t, target_endianness,
      MaximumAlignment<uint64_t, max_alignment>::value> Elf_Xword;
  typedef support::detail::packed_endian_specific_integral<
      int64_t, target_endianness,
      MaximumAlignment<int64_t, max_alignment>::value> Elf_Sxword;
};

template <class ELFT> struct ELFDataTypeTypedefHelper;

/// ELF 32bit types.
template <endianness TargetEndianness, std::size_t MaxAlign>
struct ELFDataTypeTypedefHelper<ELFType<TargetEndianness, MaxAlign, false> >
    : ELFDataTypeTypedefHelperCommon<TargetEndianness, MaxAlign> {
  typedef uint32_t value_type;
  typedef support::detail::packed_endian_specific_integral<
      value_type, TargetEndianness,
      MaximumAlignment<value_type, MaxAlign>::value> Elf_Addr;
  typedef support::detail::packed_endian_specific_integral<
      value_type, TargetEndianness,
      MaximumAlignment<value_type, MaxAlign>::value> Elf_Off;
};

/// ELF 64bit types.
template <endianness TargetEndianness, std::size_t MaxAlign>
struct ELFDataTypeTypedefHelper<ELFType<TargetEndianness, MaxAlign, true> >
    : ELFDataTypeTypedefHelperCommon<TargetEndianness, MaxAlign> {
  typedef uint64_t value_type;
  typedef support::detail::packed_endian_specific_integral<
      value_type, TargetEndianness,
      MaximumAlignment<value_type, MaxAlign>::value> Elf_Addr;
  typedef support::detail::packed_endian_specific_integral<
      value_type, TargetEndianness,
      MaximumAlignment<value_type, MaxAlign>::value> Elf_Off;
};

// I really don't like doing this, but the alternative is copypasta.
#define LLVM_ELF_IMPORT_TYPES(E, M, W)                                         \
typedef typename ELFDataTypeTypedefHelper<ELFType<E, M, W> >::Elf_Addr         \
    Elf_Addr;                                                                  \
typedef typename ELFDataTypeTypedefHelper<ELFType<E, M, W> >::Elf_Off          \
    Elf_Off;                                                                   \
typedef typename ELFDataTypeTypedefHelper<ELFType<E, M, W> >::Elf_Half         \
    Elf_Half;                                                                  \
typedef typename ELFDataTypeTypedefHelper<ELFType<E, M, W> >::Elf_Word         \
    Elf_Word;                                                                  \
typedef typename ELFDataTypeTypedefHelper<ELFType<E, M, W> >::Elf_Sword        \
    Elf_Sword;                                                                 \
typedef typename ELFDataTypeTypedefHelper<ELFType<E, M, W> >::Elf_Xword        \
    Elf_Xword;                                                                 \
typedef typename ELFDataTypeTypedefHelper<ELFType<E, M, W> >::Elf_Sxword       \
    Elf_Sxword;

#define LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)                                       \
  LLVM_ELF_IMPORT_TYPES(ELFT::TargetEndianness, ELFT::MaxAlignment,            \
                        ELFT::Is64Bits)

// Section header.
template <class ELFT> struct Elf_Shdr_Base;

template <endianness TargetEndianness, std::size_t MaxAlign>
struct Elf_Shdr_Base<ELFType<TargetEndianness, MaxAlign, false> > {
  LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false)
  Elf_Word sh_name;      // Section name (index into string table)
  Elf_Word sh_type;      // Section type (SHT_*)
  Elf_Word sh_flags;     // Section flags (SHF_*)
  Elf_Addr sh_addr;      // Address where section is to be loaded
  Elf_Off sh_offset;     // File offset of section data, in bytes
  Elf_Word sh_size;      // Size of section, in bytes
  Elf_Word sh_link;      // Section type-specific header table index link
  Elf_Word sh_info;      // Section type-specific extra information
  Elf_Word sh_addralign; // Section address alignment
  Elf_Word sh_entsize;   // Size of records contained within the section
};

template <endianness TargetEndianness, std::size_t MaxAlign>
struct Elf_Shdr_Base<ELFType<TargetEndianness, MaxAlign, true> > {
  LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true)
  Elf_Word sh_name;       // Section name (index into string table)
  Elf_Word sh_type;       // Section type (SHT_*)
  Elf_Xword sh_flags;     // Section flags (SHF_*)
  Elf_Addr sh_addr;       // Address where section is to be loaded
  Elf_Off sh_offset;      // File offset of section data, in bytes
  Elf_Xword sh_size;      // Size of section, in bytes
  Elf_Word sh_link;       // Section type-specific header table index link
  Elf_Word sh_info;       // Section type-specific extra information
  Elf_Xword sh_addralign; // Section address alignment
  Elf_Xword sh_entsize;   // Size of records contained within the section
};

template <class ELFT>
struct Elf_Shdr_Impl : Elf_Shdr_Base<ELFT> {
  using Elf_Shdr_Base<ELFT>::sh_entsize;
  using Elf_Shdr_Base<ELFT>::sh_size;

  /// @brief Get the number of entities this section contains if it has any.
  unsigned getEntityCount() const {
    if (sh_entsize == 0)
      return 0;
    return sh_size / sh_entsize;
  }
};

template <class ELFT> struct Elf_Sym_Base;

template <endianness TargetEndianness, std::size_t MaxAlign>
struct Elf_Sym_Base<ELFType<TargetEndianness, MaxAlign, false> > {
  LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false)
  Elf_Word st_name;       // Symbol name (index into string table)
  Elf_Addr st_value;      // Value or address associated with the symbol
  Elf_Word st_size;       // Size of the symbol
  unsigned char st_info;  // Symbol's type and binding attributes
  unsigned char st_other; // Must be zero; reserved
  Elf_Half st_shndx;      // Which section (header table index) it's defined in
};

template <endianness TargetEndianness, std::size_t MaxAlign>
struct Elf_Sym_Base<ELFType<TargetEndianness, MaxAlign, true> > {
  LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true)
  Elf_Word st_name;       // Symbol name (index into string table)
  unsigned char st_info;  // Symbol's type and binding attributes
  unsigned char st_other; // Must be zero; reserved
  Elf_Half st_shndx;      // Which section (header table index) it's defined in
  Elf_Addr st_value;      // Value or address associated with the symbol
  Elf_Xword st_size;      // Size of the symbol
};

template <class ELFT>
struct Elf_Sym_Impl : Elf_Sym_Base<ELFT> {
  using Elf_Sym_Base<ELFT>::st_info;

  // These accessors and mutators correspond to the ELF32_ST_BIND,
  // ELF32_ST_TYPE, and ELF32_ST_INFO macros defined in the ELF specification:
  unsigned char getBinding() const { return st_info >> 4; }
  unsigned char getType() const { return st_info & 0x0f; }
  void setBinding(unsigned char b) { setBindingAndType(b, getType()); }
  void setType(unsigned char t) { setBindingAndType(getBinding(), t); }
  void setBindingAndType(unsigned char b, unsigned char t) {
    st_info = (b << 4) + (t & 0x0f);
  }
};

/// Elf_Versym: This is the structure of entries in the SHT_GNU_versym section
/// (.gnu.version). This structure is identical for ELF32 and ELF64.
template <class ELFT>
struct Elf_Versym_Impl {
  LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
  Elf_Half vs_index; // Version index with flags (e.g. VERSYM_HIDDEN)
};

template <class ELFT> struct Elf_Verdaux_Impl;

/// Elf_Verdef: This is the structure of entries in the SHT_GNU_verdef section
/// (.gnu.version_d). This structure is identical for ELF32 and ELF64.
template <class ELFT>
struct Elf_Verdef_Impl {
  LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
  typedef Elf_Verdaux_Impl<ELFT> Elf_Verdaux;
  Elf_Half vd_version; // Version of this structure (e.g. VER_DEF_CURRENT)
  Elf_Half vd_flags;   // Bitwise flags (VER_DEF_*)
  Elf_Half vd_ndx;     // Version index, used in .gnu.version entries
  Elf_Half vd_cnt;     // Number of Verdaux entries
  Elf_Word vd_hash;    // Hash of name
  Elf_Word vd_aux;     // Offset to the first Verdaux entry (in bytes)
  Elf_Word vd_next;    // Offset to the next Verdef entry (in bytes)

  /// Get the first Verdaux entry for this Verdef.
  const Elf_Verdaux *getAux() const {
    return reinterpret_cast<const Elf_Verdaux *>((const char *)this + vd_aux);
  }
};

/// Elf_Verdaux: This is the structure of auxiliary data in the SHT_GNU_verdef
/// section (.gnu.version_d). This structure is identical for ELF32 and ELF64.
template <class ELFT>
struct Elf_Verdaux_Impl {
  LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
  Elf_Word vda_name; // Version name (offset in string table)
  Elf_Word vda_next; // Offset to next Verdaux entry (in bytes)
};

/// Elf_Verneed: This is the structure of entries in the SHT_GNU_verneed
/// section (.gnu.version_r). This structure is identical for ELF32 and ELF64.
template <class ELFT>
struct Elf_Verneed_Impl {
  LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
  Elf_Half vn_version; // Version of this structure (e.g. VER_NEED_CURRENT)
  Elf_Half vn_cnt;     // Number of associated Vernaux entries
  Elf_Word vn_file;    // Library name (string table offset)
  Elf_Word vn_aux;     // Offset to first Vernaux entry (in bytes)
  Elf_Word vn_next;    // Offset to next Verneed entry (in bytes)
};

/// Elf_Vernaux: This is the structure of auxiliary data in SHT_GNU_verneed
/// section (.gnu.version_r). This structure is identical for ELF32 and ELF64.
template <class ELFT>
struct Elf_Vernaux_Impl {
  LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
  Elf_Word vna_hash;  // Hash of dependency name
  Elf_Half vna_flags; // Bitwise Flags (VER_FLAG_*)
  Elf_Half vna_other; // Version index, used in .gnu.version entries
  Elf_Word vna_name;  // Dependency name
  Elf_Word vna_next;  // Offset to next Vernaux entry (in bytes)
};

/// Elf_Dyn_Base: This structure matches the form of entries in the dynamic
///               table section (.dynamic) look like.
template <class ELFT> struct Elf_Dyn_Base;

template <endianness TargetEndianness, std::size_t MaxAlign>
struct Elf_Dyn_Base<ELFType<TargetEndianness, MaxAlign, false> > {
  LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false)
  Elf_Sword d_tag;
  union {
    Elf_Word d_val;
    Elf_Addr d_ptr;
  } d_un;
};

template <endianness TargetEndianness, std::size_t MaxAlign>
struct Elf_Dyn_Base<ELFType<TargetEndianness, MaxAlign, true> > {
  LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true)
  Elf_Sxword d_tag;
  union {
    Elf_Xword d_val;
    Elf_Addr d_ptr;
  } d_un;
};

/// Elf_Dyn_Impl: This inherits from Elf_Dyn_Base, adding getters and setters.
template <class ELFT>
struct Elf_Dyn_Impl : Elf_Dyn_Base<ELFT> {
  using Elf_Dyn_Base<ELFT>::d_tag;
  using Elf_Dyn_Base<ELFT>::d_un;
  int64_t getTag() const { return d_tag; }
  uint64_t getVal() const { return d_un.d_val; }
  uint64_t getPtr() const { return d_un.ptr; }
};

// Elf_Rel: Elf Relocation
template <class ELFT, bool isRela> struct Elf_Rel_Base;

template <endianness TargetEndianness, std::size_t MaxAlign>
struct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, false>, false> {
  LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false)
  Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
  Elf_Word r_info;   // Symbol table index and type of relocation to apply

  uint32_t getRInfo(bool isMips64EL) const {
    assert(!isMips64EL);
    return r_info;
  }
  void setRInfo(uint32_t R) { r_info = R; }
};

template <endianness TargetEndianness, std::size_t MaxAlign>
struct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, true>, false> {
  LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true)
  Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
  Elf_Xword r_info;  // Symbol table index and type of relocation to apply

  uint64_t getRInfo(bool isMips64EL) const {
    uint64_t t = r_info;
    if (!isMips64EL)
      return t;
    // Mips64 little endian has a "special" encoding of r_info. Instead of one
    // 64 bit little endian number, it is a little endian 32 bit number followed
    // by a 32 bit big endian number.
    return (t << 32) | ((t >> 8) & 0xff000000) | ((t >> 24) & 0x00ff0000) |
           ((t >> 40) & 0x0000ff00) | ((t >> 56) & 0x000000ff);
  }
  void setRInfo(uint64_t R) {
    // FIXME: Add mips64el support.
    r_info = R;
  }
};

template <endianness TargetEndianness, std::size_t MaxAlign>
struct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, false>, true> {
  LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false)
  Elf_Addr r_offset;  // Location (file byte offset, or program virtual addr)
  Elf_Word r_info;    // Symbol table index and type of relocation to apply
  Elf_Sword r_addend; // Compute value for relocatable field by adding this

  uint32_t getRInfo(bool isMips64EL) const {
    assert(!isMips64EL);
    return r_info;
  }
  void setRInfo(uint32_t R) { r_info = R; }
};

template <endianness TargetEndianness, std::size_t MaxAlign>
struct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, true>, true> {
  LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true)
  Elf_Addr r_offset;   // Location (file byte offset, or program virtual addr)
  Elf_Xword r_info;    // Symbol table index and type of relocation to apply
  Elf_Sxword r_addend; // Compute value for relocatable field by adding this.

  uint64_t getRInfo(bool isMips64EL) const {
    // Mips64 little endian has a "special" encoding of r_info. Instead of one
    // 64 bit little endian number, it is a little endian 32 bit number followed
    // by a 32 bit big endian number.
    uint64_t t = r_info;
    if (!isMips64EL)
      return t;
    return (t << 32) | ((t >> 8) & 0xff000000) | ((t >> 24) & 0x00ff0000) |
           ((t >> 40) & 0x0000ff00) | ((t >> 56) & 0x000000ff);
  }
  void setRInfo(uint64_t R) {
    // FIXME: Add mips64el support.
    r_info = R;
  }
};

template <class ELFT, bool isRela> struct Elf_Rel_Impl;

template <endianness TargetEndianness, std::size_t MaxAlign, bool isRela>
struct Elf_Rel_Impl<ELFType<TargetEndianness, MaxAlign, true>,
                    isRela> : Elf_Rel_Base<
    ELFType<TargetEndianness, MaxAlign, true>, isRela> {
  LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true)

  // These accessors and mutators correspond to the ELF64_R_SYM, ELF64_R_TYPE,
  // and ELF64_R_INFO macros defined in the ELF specification:
  uint32_t getSymbol(bool isMips64EL) const {
    return (uint32_t)(this->getRInfo(isMips64EL) >> 32);
  }
  uint32_t getType(bool isMips64EL) const {
    return (uint32_t)(this->getRInfo(isMips64EL) & 0xffffffffL);
  }
  void setSymbol(uint32_t s) { setSymbolAndType(s, getType()); }
  void setType(uint32_t t) { setSymbolAndType(getSymbol(), t); }
  void setSymbolAndType(uint32_t s, uint32_t t) {
    this->setRInfo(((uint64_t)s << 32) + (t & 0xffffffffL));
  }
};

template <endianness TargetEndianness, std::size_t MaxAlign, bool isRela>
struct Elf_Rel_Impl<ELFType<TargetEndianness, MaxAlign, false>,
                    isRela> : Elf_Rel_Base<
    ELFType<TargetEndianness, MaxAlign, false>, isRela> {
  LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false)

  // These accessors and mutators correspond to the ELF32_R_SYM, ELF32_R_TYPE,
  // and ELF32_R_INFO macros defined in the ELF specification:
  uint32_t getSymbol(bool isMips64EL) const {
    return this->getRInfo(isMips64EL) >> 8;
  }
  unsigned char getType(bool isMips64EL) const {
    return (unsigned char)(this->getRInfo(isMips64EL) & 0x0ff);
  }
  void setSymbol(uint32_t s) { setSymbolAndType(s, getType()); }
  void setType(unsigned char t) { setSymbolAndType(getSymbol(), t); }
  void setSymbolAndType(uint32_t s, unsigned char t) {
    this->setRInfo((s << 8) + t);
  }
};

template <class ELFT>
struct Elf_Ehdr_Impl {
  LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
  unsigned char e_ident[ELF::EI_NIDENT]; // ELF Identification bytes
  Elf_Half e_type;                       // Type of file (see ET_*)
  Elf_Half e_machine;   // Required architecture for this file (see EM_*)
  Elf_Word e_version;   // Must be equal to 1
  Elf_Addr e_entry;     // Address to jump to in order to start program
  Elf_Off e_phoff;      // Program header table's file offset, in bytes
  Elf_Off e_shoff;      // Section header table's file offset, in bytes
  Elf_Word e_flags;     // Processor-specific flags
  Elf_Half e_ehsize;    // Size of ELF header, in bytes
  Elf_Half e_phentsize; // Size of an entry in the program header table
  Elf_Half e_phnum;     // Number of entries in the program header table
  Elf_Half e_shentsize; // Size of an entry in the section header table
  Elf_Half e_shnum;     // Number of entries in the section header table
  Elf_Half e_shstrndx;  // Section header table index of section name
                        // string table
  bool checkMagic() const {
    return (memcmp(e_ident, ELF::ElfMagic, strlen(ELF::ElfMagic))) == 0;
  }
  unsigned char getFileClass() const { return e_ident[ELF::EI_CLASS]; }
  unsigned char getDataEncoding() const { return e_ident[ELF::EI_DATA]; }
};

template <class ELFT> struct Elf_Phdr_Impl;

template <endianness TargetEndianness, std::size_t MaxAlign>
struct Elf_Phdr_Impl<ELFType<TargetEndianness, MaxAlign, false> > {
  LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false)
  Elf_Word p_type;   // Type of segment
  Elf_Off p_offset;  // FileOffset where segment is located, in bytes
  Elf_Addr p_vaddr;  // Virtual Address of beginning of segment
  Elf_Addr p_paddr;  // Physical address of beginning of segment (OS-specific)
  Elf_Word p_filesz; // Num. of bytes in file image of segment (may be zero)
  Elf_Word p_memsz;  // Num. of bytes in mem image of segment (may be zero)
  Elf_Word p_flags;  // Segment flags
  Elf_Word p_align;  // Segment alignment constraint
};

template <endianness TargetEndianness, std::size_t MaxAlign>
struct Elf_Phdr_Impl<ELFType<TargetEndianness, MaxAlign, true> > {
  LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true)
  Elf_Word p_type;    // Type of segment
  Elf_Word p_flags;   // Segment flags
  Elf_Off p_offset;   // FileOffset where segment is located, in bytes
  Elf_Addr p_vaddr;   // Virtual Address of beginning of segment
  Elf_Addr p_paddr;   // Physical address of beginning of segment (OS-specific)
  Elf_Xword p_filesz; // Num. of bytes in file image of segment (may be zero)
  Elf_Xword p_memsz;  // Num. of bytes in mem image of segment (may be zero)
  Elf_Xword p_align;  // Segment alignment constraint
};

} // end namespace object.
} // end namespace llvm.

#endif
