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

Generated by: LCOV version 1.13