LCOV - code coverage report
Current view: top level - include/llvm/Object - ELFTypes.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 61 66 92.4 %
Date: 2018-05-20 00:06:23 Functions: 7 13 53.8 %
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             : template <class ELFT> struct Elf_Nhdr_Impl;
      44             : template <class ELFT> class Elf_Note_Impl;
      45             : template <class ELFT> class Elf_Note_Iterator_Impl;
      46             : 
      47             : template <endianness E, bool Is64> struct ELFType {
      48             : private:
      49             :   template <typename Ty>
      50             :   using packed = support::detail::packed_endian_specific_integral<Ty, E, 1>;
      51             : 
      52             : public:
      53             :   static const endianness TargetEndianness = E;
      54             :   static const bool Is64Bits = Is64;
      55             : 
      56             :   using uint = typename std::conditional<Is64, uint64_t, uint32_t>::type;
      57             :   using Ehdr = Elf_Ehdr_Impl<ELFType<E, Is64>>;
      58             :   using Shdr = Elf_Shdr_Impl<ELFType<E, Is64>>;
      59             :   using Sym = Elf_Sym_Impl<ELFType<E, Is64>>;
      60             :   using Dyn = Elf_Dyn_Impl<ELFType<E, Is64>>;
      61             :   using Phdr = Elf_Phdr_Impl<ELFType<E, Is64>>;
      62             :   using Rel = Elf_Rel_Impl<ELFType<E, Is64>, false>;
      63             :   using Rela = Elf_Rel_Impl<ELFType<E, Is64>, true>;
      64             :   using Verdef = Elf_Verdef_Impl<ELFType<E, Is64>>;
      65             :   using Verdaux = Elf_Verdaux_Impl<ELFType<E, Is64>>;
      66             :   using Verneed = Elf_Verneed_Impl<ELFType<E, Is64>>;
      67             :   using Vernaux = Elf_Vernaux_Impl<ELFType<E, Is64>>;
      68             :   using Versym = Elf_Versym_Impl<ELFType<E, Is64>>;
      69             :   using Hash = Elf_Hash_Impl<ELFType<E, Is64>>;
      70             :   using GnuHash = Elf_GnuHash_Impl<ELFType<E, Is64>>;
      71             :   using Chdr = Elf_Chdr_Impl<ELFType<E, Is64>>;
      72             :   using Nhdr = Elf_Nhdr_Impl<ELFType<E, Is64>>;
      73             :   using Note = Elf_Note_Impl<ELFType<E, Is64>>;
      74             :   using NoteIterator = Elf_Note_Iterator_Impl<ELFType<E, Is64>>;
      75             :   using DynRange = ArrayRef<Dyn>;
      76             :   using ShdrRange = ArrayRef<Shdr>;
      77             :   using SymRange = ArrayRef<Sym>;
      78             :   using RelRange = ArrayRef<Rel>;
      79             :   using RelaRange = ArrayRef<Rela>;
      80             :   using PhdrRange = ArrayRef<Phdr>;
      81             : 
      82             :   using Half = packed<uint16_t>;
      83             :   using Word = packed<uint32_t>;
      84             :   using Sword = packed<int32_t>;
      85             :   using Xword = packed<uint64_t>;
      86             :   using Sxword = packed<int64_t>;
      87             :   using Addr = packed<uint>;
      88             :   using Off = packed<uint>;
      89             : };
      90             : 
      91             : using ELF32LE = ELFType<support::little, false>;
      92             : using ELF32BE = ELFType<support::big, false>;
      93             : using ELF64LE = ELFType<support::little, true>;
      94             : using ELF64BE = ELFType<support::big, true>;
      95             : 
      96             : // Use an alignment of 2 for the typedefs since that is the worst case for
      97             : // ELF files in archives.
      98             : 
      99             : // I really don't like doing this, but the alternative is copypasta.
     100             : #define LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)                                       \
     101             :   using Elf_Addr = typename ELFT::Addr;                                        \
     102             :   using Elf_Off = typename ELFT::Off;                                          \
     103             :   using Elf_Half = typename ELFT::Half;                                        \
     104             :   using Elf_Word = typename ELFT::Word;                                        \
     105             :   using Elf_Sword = typename ELFT::Sword;                                      \
     106             :   using Elf_Xword = typename ELFT::Xword;                                      \
     107             :   using Elf_Sxword = typename ELFT::Sxword;
     108             : 
     109             : #define LLVM_ELF_COMMA ,
     110             : #define LLVM_ELF_IMPORT_TYPES(E, W)                                            \
     111             :   LLVM_ELF_IMPORT_TYPES_ELFT(ELFType<E LLVM_ELF_COMMA W>)
     112             : 
     113             : // Section header.
     114             : template <class ELFT> struct Elf_Shdr_Base;
     115             : 
     116             : template <endianness TargetEndianness>
     117             : struct Elf_Shdr_Base<ELFType<TargetEndianness, false>> {
     118             :   LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
     119             :   Elf_Word sh_name;      // Section name (index into string table)
     120             :   Elf_Word sh_type;      // Section type (SHT_*)
     121             :   Elf_Word sh_flags;     // Section flags (SHF_*)
     122             :   Elf_Addr sh_addr;      // Address where section is to be loaded
     123             :   Elf_Off sh_offset;     // File offset of section data, in bytes
     124             :   Elf_Word sh_size;      // Size of section, in bytes
     125             :   Elf_Word sh_link;      // Section type-specific header table index link
     126             :   Elf_Word sh_info;      // Section type-specific extra information
     127             :   Elf_Word sh_addralign; // Section address alignment
     128             :   Elf_Word sh_entsize;   // Size of records contained within the section
     129             : };
     130             : 
     131             : template <endianness TargetEndianness>
     132             : struct Elf_Shdr_Base<ELFType<TargetEndianness, true>> {
     133             :   LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
     134             :   Elf_Word sh_name;       // Section name (index into string table)
     135             :   Elf_Word sh_type;       // Section type (SHT_*)
     136             :   Elf_Xword sh_flags;     // Section flags (SHF_*)
     137             :   Elf_Addr sh_addr;       // Address where section is to be loaded
     138             :   Elf_Off sh_offset;      // File offset of section data, in bytes
     139             :   Elf_Xword sh_size;      // Size of section, in bytes
     140             :   Elf_Word sh_link;       // Section type-specific header table index link
     141             :   Elf_Word sh_info;       // Section type-specific extra information
     142             :   Elf_Xword sh_addralign; // Section address alignment
     143             :   Elf_Xword sh_entsize;   // Size of records contained within the section
     144             : };
     145             : 
     146             : template <class ELFT>
     147             : struct Elf_Shdr_Impl : Elf_Shdr_Base<ELFT> {
     148             :   using Elf_Shdr_Base<ELFT>::sh_entsize;
     149             :   using Elf_Shdr_Base<ELFT>::sh_size;
     150             : 
     151             :   /// Get the number of entities this section contains if it has any.
     152             :   unsigned getEntityCount() const {
     153         437 :     if (sh_entsize == 0)
     154             :       return 0;
     155         435 :     return sh_size / sh_entsize;
     156             :   }
     157             : };
     158             : 
     159             : template <class ELFT> struct Elf_Sym_Base;
     160             : 
     161             : template <endianness TargetEndianness>
     162             : struct Elf_Sym_Base<ELFType<TargetEndianness, false>> {
     163             :   LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
     164             :   Elf_Word st_name;       // Symbol name (index into string table)
     165             :   Elf_Addr st_value;      // Value or address associated with the symbol
     166             :   Elf_Word st_size;       // Size of the symbol
     167             :   unsigned char st_info;  // Symbol's type and binding attributes
     168             :   unsigned char st_other; // Must be zero; reserved
     169             :   Elf_Half st_shndx;      // Which section (header table index) it's defined in
     170             : };
     171             : 
     172             : template <endianness TargetEndianness>
     173             : struct Elf_Sym_Base<ELFType<TargetEndianness, true>> {
     174             :   LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
     175             :   Elf_Word st_name;       // Symbol name (index into string table)
     176             :   unsigned char st_info;  // Symbol's type and binding attributes
     177             :   unsigned char st_other; // Must be zero; reserved
     178             :   Elf_Half st_shndx;      // Which section (header table index) it's defined in
     179             :   Elf_Addr st_value;      // Value or address associated with the symbol
     180             :   Elf_Xword st_size;      // Size of the symbol
     181             : };
     182             : 
     183             : template <class ELFT>
     184             : struct Elf_Sym_Impl : Elf_Sym_Base<ELFT> {
     185             :   using Elf_Sym_Base<ELFT>::st_info;
     186             :   using Elf_Sym_Base<ELFT>::st_shndx;
     187             :   using Elf_Sym_Base<ELFT>::st_other;
     188             :   using Elf_Sym_Base<ELFT>::st_value;
     189             : 
     190             :   // These accessors and mutators correspond to the ELF32_ST_BIND,
     191             :   // ELF32_ST_TYPE, and ELF32_ST_INFO macros defined in the ELF specification:
     192    21678472 :   unsigned char getBinding() const { return st_info >> 4; }
     193    32329651 :   unsigned char getType() const { return st_info & 0x0f; }
     194          50 :   uint64_t getValue() const { return st_value; }
     195         350 :   void setBinding(unsigned char b) { setBindingAndType(b, getType()); }
     196             :   void setType(unsigned char t) { setBindingAndType(getBinding(), t); }
     197             : 
     198             :   void setBindingAndType(unsigned char b, unsigned char t) {
     199       20556 :     st_info = (b << 4) + (t & 0x0f);
     200             :   }
     201             : 
     202             :   /// Access to the STV_xxx flag stored in the first two bits of st_other.
     203             :   /// STV_DEFAULT: 0
     204             :   /// STV_INTERNAL: 1
     205             :   /// STV_HIDDEN: 2
     206             :   /// STV_PROTECTED: 3
     207    10827691 :   unsigned char getVisibility() const { return st_other & 0x3; }
     208             :   void setVisibility(unsigned char v) {
     209             :     assert(v < 4 && "Invalid value for visibility");
     210       17476 :     st_other = (st_other & ~0x3) | v;
     211             :   }
     212             : 
     213             :   bool isAbsolute() const { return st_shndx == ELF::SHN_ABS; }
     214             : 
     215             :   bool isCommon() const {
     216        3330 :     return getType() == ELF::STT_COMMON || st_shndx == ELF::SHN_COMMON;
     217             :   }
     218             : 
     219             :   bool isDefined() const { return !isUndefined(); }
     220             : 
     221             :   bool isProcessorSpecific() const {
     222        1863 :     return st_shndx >= ELF::SHN_LOPROC && st_shndx <= ELF::SHN_HIPROC;
     223             :   }
     224             : 
     225             :   bool isOSSpecific() const {
     226        1859 :     return st_shndx >= ELF::SHN_LOOS && st_shndx <= ELF::SHN_HIOS;
     227             :   }
     228             : 
     229             :   bool isReserved() const {
     230             :     // ELF::SHN_HIRESERVE is 0xffff so st_shndx <= ELF::SHN_HIRESERVE is always
     231             :     // true and some compilers warn about it.
     232             :     return st_shndx >= ELF::SHN_LORESERVE;
     233             :   }
     234             : 
     235             :   bool isUndefined() const { return st_shndx == ELF::SHN_UNDEF; }
     236             : 
     237             :   bool isExternal() const {
     238             :     return getBinding() != ELF::STB_LOCAL;
     239             :   }
     240             : 
     241             :   Expected<StringRef> getName(StringRef StrTab) const;
     242             : };
     243             : 
     244             : template <class ELFT>
     245    10733815 : Expected<StringRef> Elf_Sym_Impl<ELFT>::getName(StringRef StrTab) const {
     246             :   uint32_t Offset = this->st_name;
     247    21467630 :   if (Offset >= StrTab.size())
     248           0 :     return errorCodeToError(object_error::parse_failed);
     249    10733815 :   return StringRef(StrTab.data() + Offset);
     250             : }
     251             : 
     252             : /// Elf_Versym: This is the structure of entries in the SHT_GNU_versym section
     253             : /// (.gnu.version). This structure is identical for ELF32 and ELF64.
     254             : template <class ELFT>
     255             : struct Elf_Versym_Impl {
     256             :   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
     257             :   Elf_Half vs_index; // Version index with flags (e.g. VERSYM_HIDDEN)
     258             : };
     259             : 
     260             : /// Elf_Verdef: This is the structure of entries in the SHT_GNU_verdef section
     261             : /// (.gnu.version_d). This structure is identical for ELF32 and ELF64.
     262             : template <class ELFT>
     263             : struct Elf_Verdef_Impl {
     264             :   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
     265             :   using Elf_Verdaux = Elf_Verdaux_Impl<ELFT>;
     266             :   Elf_Half vd_version; // Version of this structure (e.g. VER_DEF_CURRENT)
     267             :   Elf_Half vd_flags;   // Bitwise flags (VER_DEF_*)
     268             :   Elf_Half vd_ndx;     // Version index, used in .gnu.version entries
     269             :   Elf_Half vd_cnt;     // Number of Verdaux entries
     270             :   Elf_Word vd_hash;    // Hash of name
     271             :   Elf_Word vd_aux;     // Offset to the first Verdaux entry (in bytes)
     272             :   Elf_Word vd_next;    // Offset to the next Verdef entry (in bytes)
     273             : 
     274             :   /// Get the first Verdaux entry for this Verdef.
     275             :   const Elf_Verdaux *getAux() const {
     276         228 :     return reinterpret_cast<const Elf_Verdaux *>((const char *)this + vd_aux);
     277             :   }
     278             : };
     279             : 
     280             : /// Elf_Verdaux: This is the structure of auxiliary data in the SHT_GNU_verdef
     281             : /// section (.gnu.version_d). This structure is identical for ELF32 and ELF64.
     282             : template <class ELFT>
     283             : struct Elf_Verdaux_Impl {
     284             :   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
     285             :   Elf_Word vda_name; // Version name (offset in string table)
     286             :   Elf_Word vda_next; // Offset to next Verdaux entry (in bytes)
     287             : };
     288             : 
     289             : /// Elf_Verneed: This is the structure of entries in the SHT_GNU_verneed
     290             : /// section (.gnu.version_r). This structure is identical for ELF32 and ELF64.
     291             : template <class ELFT>
     292             : struct Elf_Verneed_Impl {
     293             :   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
     294             :   Elf_Half vn_version; // Version of this structure (e.g. VER_NEED_CURRENT)
     295             :   Elf_Half vn_cnt;     // Number of associated Vernaux entries
     296             :   Elf_Word vn_file;    // Library name (string table offset)
     297             :   Elf_Word vn_aux;     // Offset to first Vernaux entry (in bytes)
     298             :   Elf_Word vn_next;    // Offset to next Verneed entry (in bytes)
     299             : };
     300             : 
     301             : /// Elf_Vernaux: This is the structure of auxiliary data in SHT_GNU_verneed
     302             : /// section (.gnu.version_r). This structure is identical for ELF32 and ELF64.
     303             : template <class ELFT>
     304             : struct Elf_Vernaux_Impl {
     305             :   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
     306             :   Elf_Word vna_hash;  // Hash of dependency name
     307             :   Elf_Half vna_flags; // Bitwise Flags (VER_FLAG_*)
     308             :   Elf_Half vna_other; // Version index, used in .gnu.version entries
     309             :   Elf_Word vna_name;  // Dependency name
     310             :   Elf_Word vna_next;  // Offset to next Vernaux entry (in bytes)
     311             : };
     312             : 
     313             : /// Elf_Dyn_Base: This structure matches the form of entries in the dynamic
     314             : ///               table section (.dynamic) look like.
     315             : template <class ELFT> struct Elf_Dyn_Base;
     316             : 
     317             : template <endianness TargetEndianness>
     318             : struct Elf_Dyn_Base<ELFType<TargetEndianness, false>> {
     319             :   LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
     320             :   Elf_Sword d_tag;
     321             :   union {
     322             :     Elf_Word d_val;
     323             :     Elf_Addr d_ptr;
     324             :   } d_un;
     325             : };
     326             : 
     327             : template <endianness TargetEndianness>
     328             : struct Elf_Dyn_Base<ELFType<TargetEndianness, true>> {
     329             :   LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
     330             :   Elf_Sxword d_tag;
     331             :   union {
     332             :     Elf_Xword d_val;
     333             :     Elf_Addr d_ptr;
     334             :   } d_un;
     335             : };
     336             : 
     337             : /// Elf_Dyn_Impl: This inherits from Elf_Dyn_Base, adding getters.
     338             : template <class ELFT>
     339             : struct Elf_Dyn_Impl : Elf_Dyn_Base<ELFT> {
     340             :   using Elf_Dyn_Base<ELFT>::d_tag;
     341             :   using Elf_Dyn_Base<ELFT>::d_un;
     342             :   using intX_t = typename std::conditional<ELFT::Is64Bits,
     343             :                                            int64_t, int32_t>::type;
     344             :   using uintX_t = typename std::conditional<ELFT::Is64Bits,
     345             :                                             uint64_t, uint32_t>::type;
     346             :   intX_t getTag() const { return d_tag; }
     347             :   uintX_t getVal() const { return d_un.d_val; }
     348             :   uintX_t getPtr() const { return d_un.d_ptr; }
     349             : };
     350             : 
     351             : template <endianness TargetEndianness>
     352             : struct Elf_Rel_Impl<ELFType<TargetEndianness, false>, false> {
     353             :   LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
     354             :   static const bool IsRela = false;
     355             :   Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
     356             :   Elf_Word r_info;   // Symbol table index and type of relocation to apply
     357             : 
     358             :   uint32_t getRInfo(bool isMips64EL) const {
     359             :     assert(!isMips64EL);
     360             :     return r_info;
     361             :   }
     362             :   void setRInfo(uint32_t R, bool IsMips64EL) {
     363             :     assert(!IsMips64EL);
     364             :     r_info = R;
     365             :   }
     366             : 
     367             :   // These accessors and mutators correspond to the ELF32_R_SYM, ELF32_R_TYPE,
     368             :   // and ELF32_R_INFO macros defined in the ELF specification:
     369             :   uint32_t getSymbol(bool isMips64EL) const {
     370        3376 :     return this->getRInfo(isMips64EL) >> 8;
     371             :   }
     372             :   unsigned char getType(bool isMips64EL) const {
     373        1219 :     return (unsigned char)(this->getRInfo(isMips64EL) & 0x0ff);
     374             :   }
     375             :   void setSymbol(uint32_t s, bool IsMips64EL) {
     376             :     setSymbolAndType(s, getType(IsMips64EL), IsMips64EL);
     377             :   }
     378             :   void setType(unsigned char t, bool IsMips64EL) {
     379             :     setSymbolAndType(getSymbol(IsMips64EL), t, IsMips64EL);
     380             :   }
     381             :   void setSymbolAndType(uint32_t s, unsigned char t, bool IsMips64EL) {
     382         344 :     this->setRInfo((s << 8) + t, IsMips64EL);
     383             :   }
     384             : };
     385             : 
     386             : template <endianness TargetEndianness>
     387             : struct Elf_Rel_Impl<ELFType<TargetEndianness, false>, true>
     388             :     : public Elf_Rel_Impl<ELFType<TargetEndianness, false>, false> {
     389             :   LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
     390             :   static const bool IsRela = true;
     391             :   Elf_Sword r_addend; // Compute value for relocatable field by adding this
     392             : };
     393             : 
     394             : template <endianness TargetEndianness>
     395             : struct Elf_Rel_Impl<ELFType<TargetEndianness, true>, false> {
     396             :   LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
     397             :   static const bool IsRela = false;
     398             :   Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
     399             :   Elf_Xword r_info;  // Symbol table index and type of relocation to apply
     400             : 
     401             :   uint64_t getRInfo(bool isMips64EL) const {
     402             :     uint64_t t = r_info;
     403       37730 :     if (!isMips64EL)
     404             :       return t;
     405             :     // Mips64 little endian has a "special" encoding of r_info. Instead of one
     406             :     // 64 bit little endian number, it is a little endian 32 bit number followed
     407             :     // by a 32 bit big endian number.
     408         672 :     return (t << 32) | ((t >> 8) & 0xff000000) | ((t >> 24) & 0x00ff0000) |
     409         672 :            ((t >> 40) & 0x0000ff00) | ((t >> 56) & 0x000000ff);
     410             :   }
     411             : 
     412             :   void setRInfo(uint64_t R, bool IsMips64EL) {
     413         732 :     if (IsMips64EL)
     414          18 :       r_info = (R >> 32) | ((R & 0xff000000) << 8) | ((R & 0x00ff0000) << 24) |
     415          12 :                ((R & 0x0000ff00) << 40) | ((R & 0x000000ff) << 56);
     416             :     else
     417             :       r_info = R;
     418             :   }
     419             : 
     420             :   // These accessors and mutators correspond to the ELF64_R_SYM, ELF64_R_TYPE,
     421             :   // and ELF64_R_INFO macros defined in the ELF specification:
     422             :   uint32_t getSymbol(bool isMips64EL) const {
     423       27287 :     return (uint32_t)(this->getRInfo(isMips64EL) >> 32);
     424             :   }
     425             :   uint32_t getType(bool isMips64EL) const {
     426       25843 :     return (uint32_t)(this->getRInfo(isMips64EL) & 0xffffffffL);
     427             :   }
     428             :   void setSymbol(uint32_t s, bool IsMips64EL) {
     429             :     setSymbolAndType(s, getType(IsMips64EL), IsMips64EL);
     430             :   }
     431             :   void setType(uint32_t t, bool IsMips64EL) {
     432             :     setSymbolAndType(getSymbol(IsMips64EL), t, IsMips64EL);
     433             :   }
     434          37 :   void setSymbolAndType(uint32_t s, uint32_t t, bool IsMips64EL) {
     435         829 :     this->setRInfo(((uint64_t)s << 32) + (t & 0xffffffffL), IsMips64EL);
     436          37 :   }
     437             : };
     438             : 
     439             : template <endianness TargetEndianness>
     440             : struct Elf_Rel_Impl<ELFType<TargetEndianness, true>, true>
     441             :     : public Elf_Rel_Impl<ELFType<TargetEndianness, true>, false> {
     442             :   LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
     443             :   static const bool IsRela = true;
     444             :   Elf_Sxword r_addend; // Compute value for relocatable field by adding this.
     445             : };
     446             : 
     447             : template <class ELFT>
     448             : struct Elf_Ehdr_Impl {
     449             :   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
     450             :   unsigned char e_ident[ELF::EI_NIDENT]; // ELF Identification bytes
     451             :   Elf_Half e_type;                       // Type of file (see ET_*)
     452             :   Elf_Half e_machine;   // Required architecture for this file (see EM_*)
     453             :   Elf_Word e_version;   // Must be equal to 1
     454             :   Elf_Addr e_entry;     // Address to jump to in order to start program
     455             :   Elf_Off e_phoff;      // Program header table's file offset, in bytes
     456             :   Elf_Off e_shoff;      // Section header table's file offset, in bytes
     457             :   Elf_Word e_flags;     // Processor-specific flags
     458             :   Elf_Half e_ehsize;    // Size of ELF header, in bytes
     459             :   Elf_Half e_phentsize; // Size of an entry in the program header table
     460             :   Elf_Half e_phnum;     // Number of entries in the program header table
     461             :   Elf_Half e_shentsize; // Size of an entry in the section header table
     462             :   Elf_Half e_shnum;     // Number of entries in the section header table
     463             :   Elf_Half e_shstrndx;  // Section header table index of section name
     464             :                         // string table
     465             : 
     466             :   bool checkMagic() const {
     467             :     return (memcmp(e_ident, ELF::ElfMagic, strlen(ELF::ElfMagic))) == 0;
     468             :   }
     469             : 
     470             :   unsigned char getFileClass() const { return e_ident[ELF::EI_CLASS]; }
     471             :   unsigned char getDataEncoding() const { return e_ident[ELF::EI_DATA]; }
     472             : };
     473             : 
     474             : template <endianness TargetEndianness>
     475             : struct Elf_Phdr_Impl<ELFType<TargetEndianness, false>> {
     476             :   LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
     477             :   Elf_Word p_type;   // Type of segment
     478             :   Elf_Off p_offset;  // FileOffset where segment is located, in bytes
     479             :   Elf_Addr p_vaddr;  // Virtual Address of beginning of segment
     480             :   Elf_Addr p_paddr;  // Physical address of beginning of segment (OS-specific)
     481             :   Elf_Word p_filesz; // Num. of bytes in file image of segment (may be zero)
     482             :   Elf_Word p_memsz;  // Num. of bytes in mem image of segment (may be zero)
     483             :   Elf_Word p_flags;  // Segment flags
     484             :   Elf_Word p_align;  // Segment alignment constraint
     485             : };
     486             : 
     487             : template <endianness TargetEndianness>
     488             : struct Elf_Phdr_Impl<ELFType<TargetEndianness, true>> {
     489             :   LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
     490             :   Elf_Word p_type;    // Type of segment
     491             :   Elf_Word p_flags;   // Segment flags
     492             :   Elf_Off p_offset;   // FileOffset where segment is located, in bytes
     493             :   Elf_Addr p_vaddr;   // Virtual Address of beginning of segment
     494             :   Elf_Addr p_paddr;   // Physical address of beginning of segment (OS-specific)
     495             :   Elf_Xword p_filesz; // Num. of bytes in file image of segment (may be zero)
     496             :   Elf_Xword p_memsz;  // Num. of bytes in mem image of segment (may be zero)
     497             :   Elf_Xword p_align;  // Segment alignment constraint
     498             : };
     499             : 
     500             : // ELFT needed for endianness.
     501             : template <class ELFT>
     502             : struct Elf_Hash_Impl {
     503             :   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
     504             :   Elf_Word nbucket;
     505             :   Elf_Word nchain;
     506             : 
     507             :   ArrayRef<Elf_Word> buckets() const {
     508          18 :     return ArrayRef<Elf_Word>(&nbucket + 2, &nbucket + 2 + nbucket);
     509             :   }
     510             : 
     511             :   ArrayRef<Elf_Word> chains() const {
     512             :     return ArrayRef<Elf_Word>(&nbucket + 2 + nbucket,
     513           9 :                               &nbucket + 2 + nbucket + nchain);
     514             :   }
     515             : };
     516             : 
     517             : // .gnu.hash section
     518             : template <class ELFT>
     519             : struct Elf_GnuHash_Impl {
     520             :   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
     521             :   Elf_Word nbuckets;
     522             :   Elf_Word symndx;
     523             :   Elf_Word maskwords;
     524             :   Elf_Word shift2;
     525             : 
     526             :   ArrayRef<Elf_Off> filter() const {
     527          36 :     return ArrayRef<Elf_Off>(reinterpret_cast<const Elf_Off *>(&shift2 + 1),
     528          67 :                              maskwords);
     529             :   }
     530             : 
     531             :   ArrayRef<Elf_Word> buckets() const {
     532             :     return ArrayRef<Elf_Word>(
     533          42 :         reinterpret_cast<const Elf_Word *>(filter().end()), nbuckets);
     534             :   }
     535             : 
     536             :   ArrayRef<Elf_Word> values(unsigned DynamicSymCount) const {
     537          14 :     return ArrayRef<Elf_Word>(buckets().end(), DynamicSymCount - symndx);
     538             :   }
     539             : };
     540             : 
     541             : // Compressed section headers.
     542             : // http://www.sco.com/developers/gabi/latest/ch4.sheader.html#compression_header
     543             : template <endianness TargetEndianness>
     544             : struct Elf_Chdr_Impl<ELFType<TargetEndianness, false>> {
     545             :   LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
     546             :   Elf_Word ch_type;
     547             :   Elf_Word ch_size;
     548             :   Elf_Word ch_addralign;
     549             : };
     550             : 
     551             : template <endianness TargetEndianness>
     552             : struct Elf_Chdr_Impl<ELFType<TargetEndianness, true>> {
     553             :   LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
     554             :   Elf_Word ch_type;
     555             :   Elf_Word ch_reserved;
     556             :   Elf_Xword ch_size;
     557             :   Elf_Xword ch_addralign;
     558             : };
     559             : 
     560             : /// Note header
     561             : template <class ELFT>
     562             : struct Elf_Nhdr_Impl {
     563             :   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
     564             :   Elf_Word n_namesz;
     565             :   Elf_Word n_descsz;
     566             :   Elf_Word n_type;
     567             : 
     568             :   /// The alignment of the name and descriptor.
     569             :   ///
     570             :   /// Implementations differ from the specification here: in practice all
     571             :   /// variants align both the name and descriptor to 4-bytes.
     572             :   static const unsigned int Align = 4;
     573             : 
     574             :   /// Get the size of the note, including name, descriptor, and padding.
     575             :   size_t getSize() const {
     576         558 :     return sizeof(*this) + alignTo<Align>(n_namesz) + alignTo<Align>(n_descsz);
     577             :   }
     578             : };
     579             : 
     580             : /// An ELF note.
     581             : ///
     582             : /// Wraps a note header, providing methods for accessing the name and
     583             : /// descriptor safely.
     584             : template <class ELFT>
     585             : class Elf_Note_Impl {
     586             :   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
     587             : 
     588             :   const Elf_Nhdr_Impl<ELFT> &Nhdr;
     589             : 
     590             :   template <class NoteIteratorELFT> friend class Elf_Note_Iterator_Impl;
     591             : 
     592             :   Elf_Note_Impl(const Elf_Nhdr_Impl<ELFT> &Nhdr) : Nhdr(Nhdr) {}
     593             : 
     594             : public:
     595             :   /// Get the note's name, excluding the terminating null byte.
     596             :   StringRef getName() const {
     597         186 :     if (!Nhdr.n_namesz)
     598             :       return StringRef();
     599             :     return StringRef(reinterpret_cast<const char *>(&Nhdr) + sizeof(Nhdr),
     600          93 :                      Nhdr.n_namesz - 1);
     601             :   }
     602             : 
     603             :   /// Get the note's descriptor.
     604             :   ArrayRef<Elf_Word> getDesc() const {
     605          93 :     if (!Nhdr.n_descsz)
     606             :       return ArrayRef<Elf_Word>();
     607             :     return ArrayRef<Elf_Word>(
     608             :         reinterpret_cast<const Elf_Word *>(
     609          93 :             reinterpret_cast<const uint8_t *>(&Nhdr) + sizeof(Nhdr) +
     610          93 :             alignTo<Elf_Nhdr_Impl<ELFT>::Align>(Nhdr.n_namesz)),
     611         186 :         Nhdr.n_descsz);
     612             :   }
     613             : 
     614             :   /// Get the note's type.
     615          93 :   Elf_Word getType() const { return Nhdr.n_type; }
     616             : };
     617             : 
     618             : template <class ELFT>
     619             : class Elf_Note_Iterator_Impl
     620             :     : std::iterator<std::forward_iterator_tag, Elf_Note_Impl<ELFT>> {
     621             :   // Nhdr being a nullptr marks the end of iteration.
     622             :   const Elf_Nhdr_Impl<ELFT> *Nhdr = nullptr;
     623             :   size_t RemainingSize = 0u;
     624             :   Error *Err = nullptr;
     625             : 
     626             :   template <class ELFFileELFT> friend class ELFFile;
     627             : 
     628             :   // Stop iteration and indicate an overflow.
     629             :   void stopWithOverflowError() {
     630           0 :     Nhdr = nullptr;
     631           0 :     *Err = make_error<StringError>("ELF note overflows container",
     632             :                                    object_error::parse_failed);
     633             :   }
     634             : 
     635             :   // Advance Nhdr by NoteSize bytes, starting from NhdrPos.
     636             :   //
     637             :   // Assumes NoteSize <= RemainingSize. Ensures Nhdr->getSize() <= RemainingSize
     638             :   // upon returning. Handles stopping iteration when reaching the end of the
     639             :   // container, either cleanly or with an overflow error.
     640         121 :   void advanceNhdr(const uint8_t *NhdrPos, size_t NoteSize) {
     641         121 :     RemainingSize -= NoteSize;
     642         121 :     if (RemainingSize == 0u)
     643          28 :       Nhdr = nullptr;
     644          93 :     else if (sizeof(*Nhdr) > RemainingSize)
     645             :       stopWithOverflowError();
     646             :     else {
     647          93 :       Nhdr = reinterpret_cast<const Elf_Nhdr_Impl<ELFT> *>(NhdrPos + NoteSize);
     648          93 :       if (Nhdr->getSize() > RemainingSize)
     649             :         stopWithOverflowError();
     650             :     }
     651         121 :   }
     652             : 
     653           0 :   Elf_Note_Iterator_Impl() {}
     654           0 :   explicit Elf_Note_Iterator_Impl(Error &Err) : Err(&Err) {}
     655          28 :   Elf_Note_Iterator_Impl(const uint8_t *Start, size_t Size, Error &Err)
     656          28 :       : RemainingSize(Size), Err(&Err) {
     657             :     assert(Start && "ELF note iterator starting at NULL");
     658          28 :     advanceNhdr(Start, 0u);
     659             :   }
     660             : 
     661             : public:
     662          93 :   Elf_Note_Iterator_Impl &operator++() {
     663             :     assert(Nhdr && "incremented ELF note end iterator");
     664          93 :     const uint8_t *NhdrPos = reinterpret_cast<const uint8_t *>(Nhdr);
     665             :     size_t NoteSize = Nhdr->getSize();
     666          93 :     advanceNhdr(NhdrPos, NoteSize);
     667          93 :     return *this;
     668             :   }
     669             :   bool operator==(Elf_Note_Iterator_Impl Other) const {
     670             :     return Nhdr == Other.Nhdr;
     671             :   }
     672             :   bool operator!=(Elf_Note_Iterator_Impl Other) const {
     673         121 :     return !(*this == Other);
     674             :   }
     675             :   Elf_Note_Impl<ELFT> operator*() const {
     676             :     assert(Nhdr && "dereferenced ELF note end iterator");
     677             :     return Elf_Note_Impl<ELFT>(*Nhdr);
     678             :   }
     679             : };
     680             : 
     681             : // MIPS .reginfo section
     682             : template <class ELFT>
     683             : struct Elf_Mips_RegInfo;
     684             : 
     685             : template <support::endianness TargetEndianness>
     686             : struct Elf_Mips_RegInfo<ELFType<TargetEndianness, false>> {
     687             :   LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
     688             :   Elf_Word ri_gprmask;     // bit-mask of used general registers
     689             :   Elf_Word ri_cprmask[4];  // bit-mask of used co-processor registers
     690             :   Elf_Addr ri_gp_value;    // gp register value
     691             : };
     692             : 
     693             : template <support::endianness TargetEndianness>
     694             : struct Elf_Mips_RegInfo<ELFType<TargetEndianness, true>> {
     695             :   LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
     696             :   Elf_Word ri_gprmask;     // bit-mask of used general registers
     697             :   Elf_Word ri_pad;         // unused padding field
     698             :   Elf_Word ri_cprmask[4];  // bit-mask of used co-processor registers
     699             :   Elf_Addr ri_gp_value;    // gp register value
     700             : };
     701             : 
     702             : // .MIPS.options section
     703             : template <class ELFT> struct Elf_Mips_Options {
     704             :   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
     705             :   uint8_t kind;     // Determines interpretation of variable part of descriptor
     706             :   uint8_t size;     // Byte size of descriptor, including this header
     707             :   Elf_Half section; // Section header index of section affected,
     708             :                     // or 0 for global options
     709             :   Elf_Word info;    // Kind-specific information
     710             : 
     711             :   Elf_Mips_RegInfo<ELFT> &getRegInfo() {
     712             :     assert(kind == ELF::ODK_REGINFO);
     713             :     return *reinterpret_cast<Elf_Mips_RegInfo<ELFT> *>(
     714           4 :         (uint8_t *)this + sizeof(Elf_Mips_Options));
     715             :   }
     716             :   const Elf_Mips_RegInfo<ELFT> &getRegInfo() const {
     717             :     return const_cast<Elf_Mips_Options *>(this)->getRegInfo();
     718             :   }
     719             : };
     720             : 
     721             : // .MIPS.abiflags section content
     722             : template <class ELFT> struct Elf_Mips_ABIFlags {
     723             :   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
     724             :   Elf_Half version;  // Version of the structure
     725             :   uint8_t isa_level; // ISA level: 1-5, 32, and 64
     726             :   uint8_t isa_rev;   // ISA revision (0 for MIPS I - MIPS V)
     727             :   uint8_t gpr_size;  // General purpose registers size
     728             :   uint8_t cpr1_size; // Co-processor 1 registers size
     729             :   uint8_t cpr2_size; // Co-processor 2 registers size
     730             :   uint8_t fp_abi;    // Floating-point ABI flag
     731             :   Elf_Word isa_ext;  // Processor-specific extension
     732             :   Elf_Word ases;     // ASEs flags
     733             :   Elf_Word flags1;   // General flags
     734             :   Elf_Word flags2;   // General flags
     735             : };
     736             : 
     737             : } // end namespace object.
     738             : } // end namespace llvm.
     739             : 
     740             : #endif // LLVM_OBJECT_ELFTYPES_H

Generated by: LCOV version 1.13