LCOV - code coverage report
Current view: top level - include/llvm/Object - ELFTypes.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 37 38 97.4 %
Date: 2018-02-25 19:55:18 Functions: 5 5 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- ELFTypes.h - Endian specific types for ELF ---------------*- C++ -*-===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : 
      10             : #ifndef LLVM_OBJECT_ELFTYPES_H
      11             : #define LLVM_OBJECT_ELFTYPES_H
      12             : 
      13             : #include "llvm/ADT/ArrayRef.h"
      14             : #include "llvm/ADT/StringRef.h"
      15             : #include "llvm/BinaryFormat/ELF.h"
      16             : #include "llvm/Object/Error.h"
      17             : #include "llvm/Support/Endian.h"
      18             : #include "llvm/Support/Error.h"
      19             : #include <cassert>
      20             : #include <cstdint>
      21             : #include <cstring>
      22             : #include <type_traits>
      23             : 
      24             : namespace llvm {
      25             : namespace object {
      26             : 
      27             : using support::endianness;
      28             : 
      29             : template <class ELFT> struct Elf_Ehdr_Impl;
      30             : template <class ELFT> struct Elf_Shdr_Impl;
      31             : template <class ELFT> struct Elf_Sym_Impl;
      32             : template <class ELFT> struct Elf_Dyn_Impl;
      33             : template <class ELFT> struct Elf_Phdr_Impl;
      34             : template <class ELFT, bool isRela> struct Elf_Rel_Impl;
      35             : template <class ELFT> struct Elf_Verdef_Impl;
      36             : template <class ELFT> struct Elf_Verdaux_Impl;
      37             : template <class ELFT> struct Elf_Verneed_Impl;
      38             : template <class ELFT> struct Elf_Vernaux_Impl;
      39             : template <class ELFT> struct Elf_Versym_Impl;
      40             : template <class ELFT> struct Elf_Hash_Impl;
      41             : template <class ELFT> struct Elf_GnuHash_Impl;
      42             : template <class ELFT> struct Elf_Chdr_Impl;
      43             : 
      44             : template <endianness E, bool Is64> struct ELFType {
      45             : private:
      46             :   template <typename Ty>
      47             :   using packed = support::detail::packed_endian_specific_integral<Ty, E, 1>;
      48             : 
      49             : public:
      50             :   static const endianness TargetEndianness = E;
      51             :   static const bool Is64Bits = Is64;
      52             : 
      53             :   using uint = typename std::conditional<Is64, uint64_t, uint32_t>::type;
      54             :   using Ehdr = Elf_Ehdr_Impl<ELFType<E, Is64>>;
      55             :   using Shdr = Elf_Shdr_Impl<ELFType<E, Is64>>;
      56             :   using Sym = Elf_Sym_Impl<ELFType<E, Is64>>;
      57             :   using Dyn = Elf_Dyn_Impl<ELFType<E, Is64>>;
      58             :   using Phdr = Elf_Phdr_Impl<ELFType<E, Is64>>;
      59             :   using Rel = Elf_Rel_Impl<ELFType<E, Is64>, false>;
      60             :   using Rela = Elf_Rel_Impl<ELFType<E, Is64>, true>;
      61             :   using Verdef = Elf_Verdef_Impl<ELFType<E, Is64>>;
      62             :   using Verdaux = Elf_Verdaux_Impl<ELFType<E, Is64>>;
      63             :   using Verneed = Elf_Verneed_Impl<ELFType<E, Is64>>;
      64             :   using Vernaux = Elf_Vernaux_Impl<ELFType<E, Is64>>;
      65             :   using Versym = Elf_Versym_Impl<ELFType<E, Is64>>;
      66             :   using Hash = Elf_Hash_Impl<ELFType<E, Is64>>;
      67             :   using GnuHash = Elf_GnuHash_Impl<ELFType<E, Is64>>;
      68             :   using Chdr = Elf_Chdr_Impl<ELFType<E, Is64>>;
      69             :   using DynRange = ArrayRef<Dyn>;
      70             :   using ShdrRange = ArrayRef<Shdr>;
      71             :   using SymRange = ArrayRef<Sym>;
      72             :   using RelRange = ArrayRef<Rel>;
      73             :   using RelaRange = ArrayRef<Rela>;
      74             :   using PhdrRange = ArrayRef<Phdr>;
      75             : 
      76             :   using Half = packed<uint16_t>;
      77             :   using Word = packed<uint32_t>;
      78             :   using Sword = packed<int32_t>;
      79             :   using Xword = packed<uint64_t>;
      80             :   using Sxword = packed<int64_t>;
      81             :   using Addr = packed<uint>;
      82             :   using Off = packed<uint>;
      83             : };
      84             : 
      85             : using ELF32LE = ELFType<support::little, false>;
      86             : using ELF32BE = ELFType<support::big, false>;
      87             : using ELF64LE = ELFType<support::little, true>;
      88             : using ELF64BE = ELFType<support::big, true>;
      89             : 
      90             : // Use an alignment of 2 for the typedefs since that is the worst case for
      91             : // ELF files in archives.
      92             : 
      93             : // I really don't like doing this, but the alternative is copypasta.
      94             : #define LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)                                       \
      95             :   using Elf_Addr = typename ELFT::Addr;                                        \
      96             :   using Elf_Off = typename ELFT::Off;                                          \
      97             :   using Elf_Half = typename ELFT::Half;                                        \
      98             :   using Elf_Word = typename ELFT::Word;                                        \
      99             :   using Elf_Sword = typename ELFT::Sword;                                      \
     100             :   using Elf_Xword = typename ELFT::Xword;                                      \
     101             :   using Elf_Sxword = typename ELFT::Sxword;
     102             : 
     103             : #define LLVM_ELF_COMMA ,
     104             : #define LLVM_ELF_IMPORT_TYPES(E, W)                                            \
     105             :   LLVM_ELF_IMPORT_TYPES_ELFT(ELFType<E LLVM_ELF_COMMA W>)
     106             : 
     107             : // Section header.
     108             : template <class ELFT> struct Elf_Shdr_Base;
     109             : 
     110             : template <endianness TargetEndianness>
     111             : struct Elf_Shdr_Base<ELFType<TargetEndianness, false>> {
     112             :   LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
     113             :   Elf_Word sh_name;      // Section name (index into string table)
     114             :   Elf_Word sh_type;      // Section type (SHT_*)
     115             :   Elf_Word sh_flags;     // Section flags (SHF_*)
     116             :   Elf_Addr sh_addr;      // Address where section is to be loaded
     117             :   Elf_Off sh_offset;     // File offset of section data, in bytes
     118             :   Elf_Word sh_size;      // Size of section, in bytes
     119             :   Elf_Word sh_link;      // Section type-specific header table index link
     120             :   Elf_Word sh_info;      // Section type-specific extra information
     121             :   Elf_Word sh_addralign; // Section address alignment
     122             :   Elf_Word sh_entsize;   // Size of records contained within the section
     123             : };
     124             : 
     125             : template <endianness TargetEndianness>
     126             : struct Elf_Shdr_Base<ELFType<TargetEndianness, true>> {
     127             :   LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
     128             :   Elf_Word sh_name;       // Section name (index into string table)
     129             :   Elf_Word sh_type;       // Section type (SHT_*)
     130             :   Elf_Xword sh_flags;     // Section flags (SHF_*)
     131             :   Elf_Addr sh_addr;       // Address where section is to be loaded
     132             :   Elf_Off sh_offset;      // File offset of section data, in bytes
     133             :   Elf_Xword sh_size;      // Size of section, in bytes
     134             :   Elf_Word sh_link;       // Section type-specific header table index link
     135             :   Elf_Word sh_info;       // Section type-specific extra information
     136             :   Elf_Xword sh_addralign; // Section address alignment
     137             :   Elf_Xword sh_entsize;   // Size of records contained within the section
     138             : };
     139             : 
     140             : template <class ELFT>
     141             : struct Elf_Shdr_Impl : Elf_Shdr_Base<ELFT> {
     142             :   using Elf_Shdr_Base<ELFT>::sh_entsize;
     143             :   using Elf_Shdr_Base<ELFT>::sh_size;
     144             : 
     145             :   /// @brief Get the number of entities this section contains if it has any.
     146             :   unsigned getEntityCount() const {
     147         414 :     if (sh_entsize == 0)
     148             :       return 0;
     149         412 :     return sh_size / sh_entsize;
     150             :   }
     151             : };
     152             : 
     153             : template <class ELFT> struct Elf_Sym_Base;
     154             : 
     155             : template <endianness TargetEndianness>
     156             : struct Elf_Sym_Base<ELFType<TargetEndianness, false>> {
     157             :   LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
     158             :   Elf_Word st_name;       // Symbol name (index into string table)
     159             :   Elf_Addr st_value;      // Value or address associated with the symbol
     160             :   Elf_Word st_size;       // Size of the symbol
     161             :   unsigned char st_info;  // Symbol's type and binding attributes
     162             :   unsigned char st_other; // Must be zero; reserved
     163             :   Elf_Half st_shndx;      // Which section (header table index) it's defined in
     164             : };
     165             : 
     166             : template <endianness TargetEndianness>
     167             : struct Elf_Sym_Base<ELFType<TargetEndianness, true>> {
     168             :   LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
     169             :   Elf_Word st_name;       // Symbol name (index into string table)
     170             :   unsigned char st_info;  // Symbol's type and binding attributes
     171             :   unsigned char st_other; // Must be zero; reserved
     172             :   Elf_Half st_shndx;      // Which section (header table index) it's defined in
     173             :   Elf_Addr st_value;      // Value or address associated with the symbol
     174             :   Elf_Xword st_size;      // Size of the symbol
     175             : };
     176             : 
     177             : template <class ELFT>
     178             : struct Elf_Sym_Impl : Elf_Sym_Base<ELFT> {
     179             :   using Elf_Sym_Base<ELFT>::st_info;
     180             :   using Elf_Sym_Base<ELFT>::st_shndx;
     181             :   using Elf_Sym_Base<ELFT>::st_other;
     182             :   using Elf_Sym_Base<ELFT>::st_value;
     183             : 
     184             :   // These accessors and mutators correspond to the ELF32_ST_BIND,
     185             :   // ELF32_ST_TYPE, and ELF32_ST_INFO macros defined in the ELF specification:
     186    21227421 :   unsigned char getBinding() const { return st_info >> 4; }
     187    31654838 :   unsigned char getType() const { return st_info & 0x0f; }
     188          46 :   uint64_t getValue() const { return st_value; }
     189         115 :   void setBinding(unsigned char b) { setBindingAndType(b, getType()); }
     190             :   void setType(unsigned char t) { setBindingAndType(getBinding(), t); }
     191             : 
     192             :   void setBindingAndType(unsigned char b, unsigned char t) {
     193       19122 :     st_info = (b << 4) + (t & 0x0f);
     194             :   }
     195             : 
     196             :   /// Access to the STV_xxx flag stored in the first two bits of st_other.
     197             :   /// STV_DEFAULT: 0
     198             :   /// STV_INTERNAL: 1
     199             :   /// STV_HIDDEN: 2
     200             :   /// STV_PROTECTED: 3
     201    10602947 :   unsigned char getVisibility() const { return st_other & 0x3; }
     202             :   void setVisibility(unsigned char v) {
     203             :     assert(v < 4 && "Invalid value for visibility");
     204       16943 :     st_other = (st_other & ~0x3) | v;
     205             :   }
     206             : 
     207             :   bool isAbsolute() const { return st_shndx == ELF::SHN_ABS; }
     208             : 
     209             :   bool isCommon() const {
     210        3124 :     return getType() == ELF::STT_COMMON || st_shndx == ELF::SHN_COMMON;
     211             :   }
     212             : 
     213             :   bool isDefined() const { return !isUndefined(); }
     214             : 
     215             :   bool isProcessorSpecific() const {
     216        1726 :     return st_shndx >= ELF::SHN_LOPROC && st_shndx <= ELF::SHN_HIPROC;
     217             :   }
     218             : 
     219             :   bool isOSSpecific() const {
     220        1722 :     return st_shndx >= ELF::SHN_LOOS && st_shndx <= ELF::SHN_HIOS;
     221             :   }
     222             : 
     223             :   bool isReserved() const {
     224             :     // ELF::SHN_HIRESERVE is 0xffff so st_shndx <= ELF::SHN_HIRESERVE is always
     225             :     // true and some compilers warn about it.
     226             :     return st_shndx >= ELF::SHN_LORESERVE;
     227             :   }
     228             : 
     229             :   bool isUndefined() const { return st_shndx == ELF::SHN_UNDEF; }
     230             : 
     231             :   bool isExternal() const {
     232             :     return getBinding() != ELF::STB_LOCAL;
     233             :   }
     234             : 
     235             :   Expected<StringRef> getName(StringRef StrTab) const;
     236             : };
     237             : 
     238             : template <class ELFT>
     239    10509500 : Expected<StringRef> Elf_Sym_Impl<ELFT>::getName(StringRef StrTab) const {
     240             :   uint32_t Offset = this->st_name;
     241    21019000 :   if (Offset >= StrTab.size())
     242           0 :     return errorCodeToError(object_error::parse_failed);
     243    10509500 :   return StringRef(StrTab.data() + Offset);
     244             : }
     245             : 
     246             : /// Elf_Versym: This is the structure of entries in the SHT_GNU_versym section
     247             : /// (.gnu.version). This structure is identical for ELF32 and ELF64.
     248             : template <class ELFT>
     249             : struct Elf_Versym_Impl {
     250             :   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
     251             :   Elf_Half vs_index; // Version index with flags (e.g. VERSYM_HIDDEN)
     252             : };
     253             : 
     254             : /// Elf_Verdef: This is the structure of entries in the SHT_GNU_verdef section
     255             : /// (.gnu.version_d). This structure is identical for ELF32 and ELF64.
     256             : template <class ELFT>
     257             : struct Elf_Verdef_Impl {
     258             :   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
     259             :   using Elf_Verdaux = Elf_Verdaux_Impl<ELFT>;
     260             :   Elf_Half vd_version; // Version of this structure (e.g. VER_DEF_CURRENT)
     261             :   Elf_Half vd_flags;   // Bitwise flags (VER_DEF_*)
     262             :   Elf_Half vd_ndx;     // Version index, used in .gnu.version entries
     263             :   Elf_Half vd_cnt;     // Number of Verdaux entries
     264             :   Elf_Word vd_hash;    // Hash of name
     265             :   Elf_Word vd_aux;     // Offset to the first Verdaux entry (in bytes)
     266             :   Elf_Word vd_next;    // Offset to the next Verdef entry (in bytes)
     267             : 
     268             :   /// Get the first Verdaux entry for this Verdef.
     269             :   const Elf_Verdaux *getAux() const {
     270         223 :     return reinterpret_cast<const Elf_Verdaux *>((const char *)this + vd_aux);
     271             :   }
     272             : };
     273             : 
     274             : /// Elf_Verdaux: This is the structure of auxiliary data in the SHT_GNU_verdef
     275             : /// section (.gnu.version_d). This structure is identical for ELF32 and ELF64.
     276             : template <class ELFT>
     277             : struct Elf_Verdaux_Impl {
     278             :   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
     279             :   Elf_Word vda_name; // Version name (offset in string table)
     280             :   Elf_Word vda_next; // Offset to next Verdaux entry (in bytes)
     281             : };
     282             : 
     283             : /// Elf_Verneed: This is the structure of entries in the SHT_GNU_verneed
     284             : /// section (.gnu.version_r). This structure is identical for ELF32 and ELF64.
     285             : template <class ELFT>
     286             : struct Elf_Verneed_Impl {
     287             :   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
     288             :   Elf_Half vn_version; // Version of this structure (e.g. VER_NEED_CURRENT)
     289             :   Elf_Half vn_cnt;     // Number of associated Vernaux entries
     290             :   Elf_Word vn_file;    // Library name (string table offset)
     291             :   Elf_Word vn_aux;     // Offset to first Vernaux entry (in bytes)
     292             :   Elf_Word vn_next;    // Offset to next Verneed entry (in bytes)
     293             : };
     294             : 
     295             : /// Elf_Vernaux: This is the structure of auxiliary data in SHT_GNU_verneed
     296             : /// section (.gnu.version_r). This structure is identical for ELF32 and ELF64.
     297             : template <class ELFT>
     298             : struct Elf_Vernaux_Impl {
     299             :   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
     300             :   Elf_Word vna_hash;  // Hash of dependency name
     301             :   Elf_Half vna_flags; // Bitwise Flags (VER_FLAG_*)
     302             :   Elf_Half vna_other; // Version index, used in .gnu.version entries
     303             :   Elf_Word vna_name;  // Dependency name
     304             :   Elf_Word vna_next;  // Offset to next Vernaux entry (in bytes)
     305             : };
     306             : 
     307             : /// Elf_Dyn_Base: This structure matches the form of entries in the dynamic
     308             : ///               table section (.dynamic) look like.
     309             : template <class ELFT> struct Elf_Dyn_Base;
     310             : 
     311             : template <endianness TargetEndianness>
     312             : struct Elf_Dyn_Base<ELFType<TargetEndianness, false>> {
     313             :   LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
     314             :   Elf_Sword d_tag;
     315             :   union {
     316             :     Elf_Word d_val;
     317             :     Elf_Addr d_ptr;
     318             :   } d_un;
     319             : };
     320             : 
     321             : template <endianness TargetEndianness>
     322             : struct Elf_Dyn_Base<ELFType<TargetEndianness, true>> {
     323             :   LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
     324             :   Elf_Sxword d_tag;
     325             :   union {
     326             :     Elf_Xword d_val;
     327             :     Elf_Addr d_ptr;
     328             :   } d_un;
     329             : };
     330             : 
     331             : /// Elf_Dyn_Impl: This inherits from Elf_Dyn_Base, adding getters.
     332             : template <class ELFT>
     333             : struct Elf_Dyn_Impl : Elf_Dyn_Base<ELFT> {
     334             :   using Elf_Dyn_Base<ELFT>::d_tag;
     335             :   using Elf_Dyn_Base<ELFT>::d_un;
     336             :   using intX_t = typename std::conditional<ELFT::Is64Bits,
     337             :                                            int64_t, int32_t>::type;
     338             :   using uintX_t = typename std::conditional<ELFT::Is64Bits,
     339             :                                             uint64_t, uint32_t>::type;
     340             :   intX_t getTag() const { return d_tag; }
     341             :   uintX_t getVal() const { return d_un.d_val; }
     342             :   uintX_t getPtr() const { return d_un.d_ptr; }
     343             : };
     344             : 
     345             : template <endianness TargetEndianness>
     346             : struct Elf_Rel_Impl<ELFType<TargetEndianness, false>, false> {
     347             :   LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
     348             :   static const bool IsRela = false;
     349             :   Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
     350             :   Elf_Word r_info;   // Symbol table index and type of relocation to apply
     351             : 
     352             :   uint32_t getRInfo(bool isMips64EL) const {
     353             :     assert(!isMips64EL);
     354             :     return r_info;
     355             :   }
     356             :   void setRInfo(uint32_t R, bool IsMips64EL) {
     357             :     assert(!IsMips64EL);
     358             :     r_info = R;
     359             :   }
     360             : 
     361             :   // These accessors and mutators correspond to the ELF32_R_SYM, ELF32_R_TYPE,
     362             :   // and ELF32_R_INFO macros defined in the ELF specification:
     363             :   uint32_t getSymbol(bool isMips64EL) const {
     364        3322 :     return this->getRInfo(isMips64EL) >> 8;
     365             :   }
     366             :   unsigned char getType(bool isMips64EL) const {
     367        1202 :     return (unsigned char)(this->getRInfo(isMips64EL) & 0x0ff);
     368             :   }
     369             :   void setSymbol(uint32_t s, bool IsMips64EL) {
     370             :     setSymbolAndType(s, getType(IsMips64EL), IsMips64EL);
     371             :   }
     372             :   void setType(unsigned char t, bool IsMips64EL) {
     373             :     setSymbolAndType(getSymbol(IsMips64EL), t, IsMips64EL);
     374             :   }
     375             :   void setSymbolAndType(uint32_t s, unsigned char t, bool IsMips64EL) {
     376         334 :     this->setRInfo((s << 8) + t, IsMips64EL);
     377             :   }
     378             : };
     379             : 
     380             : template <endianness TargetEndianness>
     381             : struct Elf_Rel_Impl<ELFType<TargetEndianness, false>, true>
     382             :     : public Elf_Rel_Impl<ELFType<TargetEndianness, false>, false> {
     383             :   LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
     384             :   static const bool IsRela = true;
     385             :   Elf_Sword r_addend; // Compute value for relocatable field by adding this
     386             : };
     387             : 
     388             : template <endianness TargetEndianness>
     389             : struct Elf_Rel_Impl<ELFType<TargetEndianness, true>, false> {
     390             :   LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
     391             :   static const bool IsRela = false;
     392             :   Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
     393             :   Elf_Xword r_info;  // Symbol table index and type of relocation to apply
     394             : 
     395             :   uint64_t getRInfo(bool isMips64EL) const {
     396             :     uint64_t t = r_info;
     397       37046 :     if (!isMips64EL)
     398             :       return t;
     399             :     // Mips64 little endian has a "special" encoding of r_info. Instead of one
     400             :     // 64 bit little endian number, it is a little endian 32 bit number followed
     401             :     // by a 32 bit big endian number.
     402         672 :     return (t << 32) | ((t >> 8) & 0xff000000) | ((t >> 24) & 0x00ff0000) |
     403         672 :            ((t >> 40) & 0x0000ff00) | ((t >> 56) & 0x000000ff);
     404             :   }
     405             : 
     406             :   void setRInfo(uint64_t R, bool IsMips64EL) {
     407         687 :     if (IsMips64EL)
     408          18 :       r_info = (R >> 32) | ((R & 0xff000000) << 8) | ((R & 0x00ff0000) << 24) |
     409          12 :                ((R & 0x0000ff00) << 40) | ((R & 0x000000ff) << 56);
     410             :     else
     411             :       r_info = R;
     412             :   }
     413             : 
     414             :   // These accessors and mutators correspond to the ELF64_R_SYM, ELF64_R_TYPE,
     415             :   // and ELF64_R_INFO macros defined in the ELF specification:
     416             :   uint32_t getSymbol(bool isMips64EL) const {
     417       21010 :     return (uint32_t)(this->getRInfo(isMips64EL) >> 32);
     418             :   }
     419             :   uint32_t getType(bool isMips64EL) const {
     420       25288 :     return (uint32_t)(this->getRInfo(isMips64EL) & 0xffffffffL);
     421             :   }
     422             :   void setSymbol(uint32_t s, bool IsMips64EL) {
     423             :     setSymbolAndType(s, getType(IsMips64EL), IsMips64EL);
     424             :   }
     425             :   void setType(uint32_t t, bool IsMips64EL) {
     426             :     setSymbolAndType(getSymbol(IsMips64EL), t, IsMips64EL);
     427             :   }
     428          39 :   void setSymbolAndType(uint32_t s, uint32_t t, bool IsMips64EL) {
     429         735 :     this->setRInfo(((uint64_t)s << 32) + (t & 0xffffffffL), IsMips64EL);
     430          39 :   }
     431             : };
     432             : 
     433             : template <endianness TargetEndianness>
     434             : struct Elf_Rel_Impl<ELFType<TargetEndianness, true>, true>
     435             :     : public Elf_Rel_Impl<ELFType<TargetEndianness, true>, false> {
     436             :   LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
     437             :   static const bool IsRela = true;
     438             :   Elf_Sxword r_addend; // Compute value for relocatable field by adding this.
     439             : };
     440             : 
     441             : template <class ELFT>
     442             : struct Elf_Ehdr_Impl {
     443             :   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
     444             :   unsigned char e_ident[ELF::EI_NIDENT]; // ELF Identification bytes
     445             :   Elf_Half e_type;                       // Type of file (see ET_*)
     446             :   Elf_Half e_machine;   // Required architecture for this file (see EM_*)
     447             :   Elf_Word e_version;   // Must be equal to 1
     448             :   Elf_Addr e_entry;     // Address to jump to in order to start program
     449             :   Elf_Off e_phoff;      // Program header table's file offset, in bytes
     450             :   Elf_Off e_shoff;      // Section header table's file offset, in bytes
     451             :   Elf_Word e_flags;     // Processor-specific flags
     452             :   Elf_Half e_ehsize;    // Size of ELF header, in bytes
     453             :   Elf_Half e_phentsize; // Size of an entry in the program header table
     454             :   Elf_Half e_phnum;     // Number of entries in the program header table
     455             :   Elf_Half e_shentsize; // Size of an entry in the section header table
     456             :   Elf_Half e_shnum;     // Number of entries in the section header table
     457             :   Elf_Half e_shstrndx;  // Section header table index of section name
     458             :                         // string table
     459             : 
     460             :   bool checkMagic() const {
     461             :     return (memcmp(e_ident, ELF::ElfMagic, strlen(ELF::ElfMagic))) == 0;
     462             :   }
     463             : 
     464             :   unsigned char getFileClass() const { return e_ident[ELF::EI_CLASS]; }
     465             :   unsigned char getDataEncoding() const { return e_ident[ELF::EI_DATA]; }
     466             : };
     467             : 
     468             : template <endianness TargetEndianness>
     469             : struct Elf_Phdr_Impl<ELFType<TargetEndianness, false>> {
     470             :   LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
     471             :   Elf_Word p_type;   // Type of segment
     472             :   Elf_Off p_offset;  // FileOffset where segment is located, in bytes
     473             :   Elf_Addr p_vaddr;  // Virtual Address of beginning of segment
     474             :   Elf_Addr p_paddr;  // Physical address of beginning of segment (OS-specific)
     475             :   Elf_Word p_filesz; // Num. of bytes in file image of segment (may be zero)
     476             :   Elf_Word p_memsz;  // Num. of bytes in mem image of segment (may be zero)
     477             :   Elf_Word p_flags;  // Segment flags
     478             :   Elf_Word p_align;  // Segment alignment constraint
     479             : };
     480             : 
     481             : template <endianness TargetEndianness>
     482             : struct Elf_Phdr_Impl<ELFType<TargetEndianness, true>> {
     483             :   LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
     484             :   Elf_Word p_type;    // Type of segment
     485             :   Elf_Word p_flags;   // Segment flags
     486             :   Elf_Off p_offset;   // FileOffset where segment is located, in bytes
     487             :   Elf_Addr p_vaddr;   // Virtual Address of beginning of segment
     488             :   Elf_Addr p_paddr;   // Physical address of beginning of segment (OS-specific)
     489             :   Elf_Xword p_filesz; // Num. of bytes in file image of segment (may be zero)
     490             :   Elf_Xword p_memsz;  // Num. of bytes in mem image of segment (may be zero)
     491             :   Elf_Xword p_align;  // Segment alignment constraint
     492             : };
     493             : 
     494             : // ELFT needed for endianness.
     495             : template <class ELFT>
     496             : struct Elf_Hash_Impl {
     497             :   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
     498             :   Elf_Word nbucket;
     499             :   Elf_Word nchain;
     500             : 
     501             :   ArrayRef<Elf_Word> buckets() const {
     502          15 :     return ArrayRef<Elf_Word>(&nbucket + 2, &nbucket + 2 + nbucket);
     503             :   }
     504             : 
     505             :   ArrayRef<Elf_Word> chains() const {
     506             :     return ArrayRef<Elf_Word>(&nbucket + 2 + nbucket,
     507           9 :                               &nbucket + 2 + nbucket + nchain);
     508             :   }
     509             : };
     510             : 
     511             : // .gnu.hash section
     512             : template <class ELFT>
     513             : struct Elf_GnuHash_Impl {
     514             :   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
     515             :   Elf_Word nbuckets;
     516             :   Elf_Word symndx;
     517             :   Elf_Word maskwords;
     518             :   Elf_Word shift2;
     519             : 
     520             :   ArrayRef<Elf_Off> filter() const {
     521          30 :     return ArrayRef<Elf_Off>(reinterpret_cast<const Elf_Off *>(&shift2 + 1),
     522          60 :                              maskwords);
     523             :   }
     524             : 
     525             :   ArrayRef<Elf_Word> buckets() const {
     526             :     return ArrayRef<Elf_Word>(
     527          39 :         reinterpret_cast<const Elf_Word *>(filter().end()), nbuckets);
     528             :   }
     529             : 
     530             :   ArrayRef<Elf_Word> values(unsigned DynamicSymCount) const {
     531          13 :     return ArrayRef<Elf_Word>(buckets().end(), DynamicSymCount - symndx);
     532             :   }
     533             : };
     534             : 
     535             : // Compressed section headers.
     536             : // http://www.sco.com/developers/gabi/latest/ch4.sheader.html#compression_header
     537             : template <endianness TargetEndianness>
     538             : struct Elf_Chdr_Impl<ELFType<TargetEndianness, false>> {
     539             :   LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
     540             :   Elf_Word ch_type;
     541             :   Elf_Word ch_size;
     542             :   Elf_Word ch_addralign;
     543             : };
     544             : 
     545             : template <endianness TargetEndianness>
     546             : struct Elf_Chdr_Impl<ELFType<TargetEndianness, true>> {
     547             :   LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
     548             :   Elf_Word ch_type;
     549             :   Elf_Word ch_reserved;
     550             :   Elf_Xword ch_size;
     551             :   Elf_Xword ch_addralign;
     552             : };
     553             : 
     554             : // MIPS .reginfo section
     555             : template <class ELFT>
     556             : struct Elf_Mips_RegInfo;
     557             : 
     558             : template <support::endianness TargetEndianness>
     559             : struct Elf_Mips_RegInfo<ELFType<TargetEndianness, false>> {
     560             :   LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
     561             :   Elf_Word ri_gprmask;     // bit-mask of used general registers
     562             :   Elf_Word ri_cprmask[4];  // bit-mask of used co-processor registers
     563             :   Elf_Addr ri_gp_value;    // gp register value
     564             : };
     565             : 
     566             : template <support::endianness TargetEndianness>
     567             : struct Elf_Mips_RegInfo<ELFType<TargetEndianness, true>> {
     568             :   LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
     569             :   Elf_Word ri_gprmask;     // bit-mask of used general registers
     570             :   Elf_Word ri_pad;         // unused padding field
     571             :   Elf_Word ri_cprmask[4];  // bit-mask of used co-processor registers
     572             :   Elf_Addr ri_gp_value;    // gp register value
     573             : };
     574             : 
     575             : // .MIPS.options section
     576             : template <class ELFT> struct Elf_Mips_Options {
     577             :   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
     578             :   uint8_t kind;     // Determines interpretation of variable part of descriptor
     579             :   uint8_t size;     // Byte size of descriptor, including this header
     580             :   Elf_Half section; // Section header index of section affected,
     581             :                     // or 0 for global options
     582             :   Elf_Word info;    // Kind-specific information
     583             : 
     584             :   Elf_Mips_RegInfo<ELFT> &getRegInfo() {
     585             :     assert(kind == ELF::ODK_REGINFO);
     586             :     return *reinterpret_cast<Elf_Mips_RegInfo<ELFT> *>(
     587           2 :         (uint8_t *)this + sizeof(Elf_Mips_Options));
     588             :   }
     589             :   const Elf_Mips_RegInfo<ELFT> &getRegInfo() const {
     590             :     return const_cast<Elf_Mips_Options *>(this)->getRegInfo();
     591             :   }
     592             : };
     593             : 
     594             : // .MIPS.abiflags section content
     595             : template <class ELFT> struct Elf_Mips_ABIFlags {
     596             :   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
     597             :   Elf_Half version;  // Version of the structure
     598             :   uint8_t isa_level; // ISA level: 1-5, 32, and 64
     599             :   uint8_t isa_rev;   // ISA revision (0 for MIPS I - MIPS V)
     600             :   uint8_t gpr_size;  // General purpose registers size
     601             :   uint8_t cpr1_size; // Co-processor 1 registers size
     602             :   uint8_t cpr2_size; // Co-processor 2 registers size
     603             :   uint8_t fp_abi;    // Floating-point ABI flag
     604             :   Elf_Word isa_ext;  // Processor-specific extension
     605             :   Elf_Word ases;     // ASEs flags
     606             :   Elf_Word flags1;   // General flags
     607             :   Elf_Word flags2;   // General flags
     608             : };
     609             : 
     610             : } // end namespace object.
     611             : } // end namespace llvm.
     612             : 
     613             : #endif // LLVM_OBJECT_ELFTYPES_H

Generated by: LCOV version 1.13