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

Generated by: LCOV version 1.13