Home | History | Annotate | Line # | Download | only in Object
      1 //===- ELFTypes.h - Endian specific types for ELF ---------------*- C++ -*-===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 
      9 #ifndef LLVM_OBJECT_ELFTYPES_H
     10 #define LLVM_OBJECT_ELFTYPES_H
     11 
     12 #include "llvm/ADT/ArrayRef.h"
     13 #include "llvm/ADT/StringRef.h"
     14 #include "llvm/BinaryFormat/ELF.h"
     15 #include "llvm/Object/Error.h"
     16 #include "llvm/Support/Endian.h"
     17 #include "llvm/Support/Error.h"
     18 #include <cassert>
     19 #include <cstdint>
     20 #include <cstring>
     21 #include <type_traits>
     22 
     23 namespace llvm {
     24 namespace object {
     25 
     26 using support::endianness;
     27 
     28 template <class ELFT> struct Elf_Ehdr_Impl;
     29 template <class ELFT> struct Elf_Shdr_Impl;
     30 template <class ELFT> struct Elf_Sym_Impl;
     31 template <class ELFT> struct Elf_Dyn_Impl;
     32 template <class ELFT> struct Elf_Phdr_Impl;
     33 template <class ELFT, bool isRela> struct Elf_Rel_Impl;
     34 template <class ELFT> struct Elf_Verdef_Impl;
     35 template <class ELFT> struct Elf_Verdaux_Impl;
     36 template <class ELFT> struct Elf_Verneed_Impl;
     37 template <class ELFT> struct Elf_Vernaux_Impl;
     38 template <class ELFT> struct Elf_Versym_Impl;
     39 template <class ELFT> struct Elf_Hash_Impl;
     40 template <class ELFT> struct Elf_GnuHash_Impl;
     41 template <class ELFT> struct Elf_Chdr_Impl;
     42 template <class ELFT> struct Elf_Nhdr_Impl;
     43 template <class ELFT> class Elf_Note_Impl;
     44 template <class ELFT> class Elf_Note_Iterator_Impl;
     45 template <class ELFT> struct Elf_CGProfile_Impl;
     46 template <class ELFT> struct Elf_BBAddrMap_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 = std::conditional_t<Is64, uint64_t, uint32_t>;
     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 BBAddrMap = Elf_BBAddrMap_Impl<ELFType<E, Is64>>;
     79   using DynRange = ArrayRef<Dyn>;
     80   using ShdrRange = ArrayRef<Shdr>;
     81   using SymRange = ArrayRef<Sym>;
     82   using RelRange = ArrayRef<Rel>;
     83   using RelaRange = ArrayRef<Rela>;
     84   using RelrRange = ArrayRef<Relr>;
     85   using PhdrRange = ArrayRef<Phdr>;
     86 
     87   using Half = packed<uint16_t>;
     88   using Word = packed<uint32_t>;
     89   using Sword = packed<int32_t>;
     90   using Xword = packed<uint64_t>;
     91   using Sxword = packed<int64_t>;
     92   using Addr = packed<uint>;
     93   using Off = packed<uint>;
     94 };
     95 
     96 using ELF32LE = ELFType<support::little, false>;
     97 using ELF32BE = ELFType<support::big, false>;
     98 using ELF64LE = ELFType<support::little, true>;
     99 using ELF64BE = ELFType<support::big, true>;
    100 
    101 // Use an alignment of 2 for the typedefs since that is the worst case for
    102 // ELF files in archives.
    103 
    104 // I really don't like doing this, but the alternative is copypasta.
    105 #define LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)                                       \
    106   using Elf_Addr = typename ELFT::Addr;                                        \
    107   using Elf_Off = typename ELFT::Off;                                          \
    108   using Elf_Half = typename ELFT::Half;                                        \
    109   using Elf_Word = typename ELFT::Word;                                        \
    110   using Elf_Sword = typename ELFT::Sword;                                      \
    111   using Elf_Xword = typename ELFT::Xword;                                      \
    112   using Elf_Sxword = typename ELFT::Sxword;                                    \
    113   using uintX_t = typename ELFT::uint;                                         \
    114   using Elf_Ehdr = typename ELFT::Ehdr;                                        \
    115   using Elf_Shdr = typename ELFT::Shdr;                                        \
    116   using Elf_Sym = typename ELFT::Sym;                                          \
    117   using Elf_Dyn = typename ELFT::Dyn;                                          \
    118   using Elf_Phdr = typename ELFT::Phdr;                                        \
    119   using Elf_Rel = typename ELFT::Rel;                                          \
    120   using Elf_Rela = typename ELFT::Rela;                                        \
    121   using Elf_Relr = typename ELFT::Relr;                                        \
    122   using Elf_Verdef = typename ELFT::Verdef;                                    \
    123   using Elf_Verdaux = typename ELFT::Verdaux;                                  \
    124   using Elf_Verneed = typename ELFT::Verneed;                                  \
    125   using Elf_Vernaux = typename ELFT::Vernaux;                                  \
    126   using Elf_Versym = typename ELFT::Versym;                                    \
    127   using Elf_Hash = typename ELFT::Hash;                                        \
    128   using Elf_GnuHash = typename ELFT::GnuHash;                                  \
    129   using Elf_Nhdr = typename ELFT::Nhdr;                                        \
    130   using Elf_Note = typename ELFT::Note;                                        \
    131   using Elf_Note_Iterator = typename ELFT::NoteIterator;                       \
    132   using Elf_CGProfile = typename ELFT::CGProfile;                              \
    133   using Elf_BBAddrMap = typename ELFT::BBAddrMap;                              \
    134   using Elf_Dyn_Range = typename ELFT::DynRange;                               \
    135   using Elf_Shdr_Range = typename ELFT::ShdrRange;                             \
    136   using Elf_Sym_Range = typename ELFT::SymRange;                               \
    137   using Elf_Rel_Range = typename ELFT::RelRange;                               \
    138   using Elf_Rela_Range = typename ELFT::RelaRange;                             \
    139   using Elf_Relr_Range = typename ELFT::RelrRange;                             \
    140   using Elf_Phdr_Range = typename ELFT::PhdrRange;
    141 
    142 #define LLVM_ELF_COMMA ,
    143 #define LLVM_ELF_IMPORT_TYPES(E, W)                                            \
    144   LLVM_ELF_IMPORT_TYPES_ELFT(ELFType<E LLVM_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   /// Get the number of entities this section contains if it has any.
    185   unsigned getEntityCount() const {
    186     if (sh_entsize == 0)
    187       return 0;
    188     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   unsigned char getBinding() const { return st_info >> 4; }
    226   unsigned char getType() const { return st_info & 0x0f; }
    227   uint64_t getValue() const { return st_value; }
    228   void setBinding(unsigned char b) { setBindingAndType(b, getType()); }
    229   void setType(unsigned char t) { setBindingAndType(getBinding(), t); }
    230 
    231   void setBindingAndType(unsigned char b, unsigned char t) {
    232     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   unsigned char getVisibility() const { return st_other & 0x3; }
    241   void setVisibility(unsigned char v) {
    242     assert(v < 4 && "Invalid value for visibility");
    243     st_other = (st_other & ~0x3) | v;
    244   }
    245 
    246   bool isAbsolute() const { return st_shndx == ELF::SHN_ABS; }
    247 
    248   bool isCommon() const {
    249     return getType() == ELF::STT_COMMON || st_shndx == ELF::SHN_COMMON;
    250   }
    251 
    252   bool isDefined() const { return !isUndefined(); }
    253 
    254   bool isProcessorSpecific() const {
    255     return st_shndx >= ELF::SHN_LOPROC && st_shndx <= ELF::SHN_HIPROC;
    256   }
    257 
    258   bool isOSSpecific() const {
    259     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     return st_shndx >= ELF::SHN_LORESERVE;
    266   }
    267 
    268   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 Expected<StringRef> Elf_Sym_Impl<ELFT>::getName(StringRef StrTab) const {
    279   uint32_t Offset = this->st_name;
    280   if (Offset >= StrTab.size())
    281     return createStringError(object_error::parse_failed,
    282                              "st_name (0x%" PRIx32
    283                              ") is past the end of the string table"
    284                              " of size 0x%zx",
    285                              Offset, StrTab.size());
    286   return StringRef(StrTab.data() + Offset);
    287 }
    288 
    289 /// Elf_Versym: This is the structure of entries in the SHT_GNU_versym section
    290 /// (.gnu.version). This structure is identical for ELF32 and ELF64.
    291 template <class ELFT>
    292 struct Elf_Versym_Impl {
    293   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
    294   Elf_Half vs_index; // Version index with flags (e.g. VERSYM_HIDDEN)
    295 };
    296 
    297 /// Elf_Verdef: This is the structure of entries in the SHT_GNU_verdef section
    298 /// (.gnu.version_d). This structure is identical for ELF32 and ELF64.
    299 template <class ELFT>
    300 struct Elf_Verdef_Impl {
    301   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
    302   Elf_Half vd_version; // Version of this structure (e.g. VER_DEF_CURRENT)
    303   Elf_Half vd_flags;   // Bitwise flags (VER_DEF_*)
    304   Elf_Half vd_ndx;     // Version index, used in .gnu.version entries
    305   Elf_Half vd_cnt;     // Number of Verdaux entries
    306   Elf_Word vd_hash;    // Hash of name
    307   Elf_Word vd_aux;     // Offset to the first Verdaux entry (in bytes)
    308   Elf_Word vd_next;    // Offset to the next Verdef entry (in bytes)
    309 
    310   /// Get the first Verdaux entry for this Verdef.
    311   const Elf_Verdaux *getAux() const {
    312     return reinterpret_cast<const Elf_Verdaux *>((const char *)this + vd_aux);
    313   }
    314 };
    315 
    316 /// Elf_Verdaux: This is the structure of auxiliary data in the SHT_GNU_verdef
    317 /// section (.gnu.version_d). This structure is identical for ELF32 and ELF64.
    318 template <class ELFT>
    319 struct Elf_Verdaux_Impl {
    320   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
    321   Elf_Word vda_name; // Version name (offset in string table)
    322   Elf_Word vda_next; // Offset to next Verdaux entry (in bytes)
    323 };
    324 
    325 /// Elf_Verneed: This is the structure of entries in the SHT_GNU_verneed
    326 /// section (.gnu.version_r). This structure is identical for ELF32 and ELF64.
    327 template <class ELFT>
    328 struct Elf_Verneed_Impl {
    329   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
    330   Elf_Half vn_version; // Version of this structure (e.g. VER_NEED_CURRENT)
    331   Elf_Half vn_cnt;     // Number of associated Vernaux entries
    332   Elf_Word vn_file;    // Library name (string table offset)
    333   Elf_Word vn_aux;     // Offset to first Vernaux entry (in bytes)
    334   Elf_Word vn_next;    // Offset to next Verneed entry (in bytes)
    335 };
    336 
    337 /// Elf_Vernaux: This is the structure of auxiliary data in SHT_GNU_verneed
    338 /// section (.gnu.version_r). This structure is identical for ELF32 and ELF64.
    339 template <class ELFT>
    340 struct Elf_Vernaux_Impl {
    341   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
    342   Elf_Word vna_hash;  // Hash of dependency name
    343   Elf_Half vna_flags; // Bitwise Flags (VER_FLAG_*)
    344   Elf_Half vna_other; // Version index, used in .gnu.version entries
    345   Elf_Word vna_name;  // Dependency name
    346   Elf_Word vna_next;  // Offset to next Vernaux entry (in bytes)
    347 };
    348 
    349 /// Elf_Dyn_Base: This structure matches the form of entries in the dynamic
    350 ///               table section (.dynamic) look like.
    351 template <class ELFT> struct Elf_Dyn_Base;
    352 
    353 template <endianness TargetEndianness>
    354 struct Elf_Dyn_Base<ELFType<TargetEndianness, false>> {
    355   LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
    356   Elf_Sword d_tag;
    357   union {
    358     Elf_Word d_val;
    359     Elf_Addr d_ptr;
    360   } d_un;
    361 };
    362 
    363 template <endianness TargetEndianness>
    364 struct Elf_Dyn_Base<ELFType<TargetEndianness, true>> {
    365   LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
    366   Elf_Sxword d_tag;
    367   union {
    368     Elf_Xword d_val;
    369     Elf_Addr d_ptr;
    370   } d_un;
    371 };
    372 
    373 /// Elf_Dyn_Impl: This inherits from Elf_Dyn_Base, adding getters.
    374 template <class ELFT>
    375 struct Elf_Dyn_Impl : Elf_Dyn_Base<ELFT> {
    376   using Elf_Dyn_Base<ELFT>::d_tag;
    377   using Elf_Dyn_Base<ELFT>::d_un;
    378   using intX_t = std::conditional_t<ELFT::Is64Bits, int64_t, int32_t>;
    379   using uintX_t = std::conditional_t<ELFT::Is64Bits, uint64_t, uint32_t>;
    380   intX_t getTag() const { return d_tag; }
    381   uintX_t getVal() const { return d_un.d_val; }
    382   uintX_t getPtr() const { return d_un.d_ptr; }
    383 };
    384 
    385 template <endianness TargetEndianness>
    386 struct Elf_Rel_Impl<ELFType<TargetEndianness, false>, false> {
    387   LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
    388   static const bool IsRela = false;
    389   Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
    390   Elf_Word r_info;   // Symbol table index and type of relocation to apply
    391 
    392   uint32_t getRInfo(bool isMips64EL) const {
    393     assert(!isMips64EL);
    394     return r_info;
    395   }
    396   void setRInfo(uint32_t R, bool IsMips64EL) {
    397     assert(!IsMips64EL);
    398     r_info = R;
    399   }
    400 
    401   // These accessors and mutators correspond to the ELF32_R_SYM, ELF32_R_TYPE,
    402   // and ELF32_R_INFO macros defined in the ELF specification:
    403   uint32_t getSymbol(bool isMips64EL) const {
    404     return this->getRInfo(isMips64EL) >> 8;
    405   }
    406   unsigned char getType(bool isMips64EL) const {
    407     return (unsigned char)(this->getRInfo(isMips64EL) & 0x0ff);
    408   }
    409   void setSymbol(uint32_t s, bool IsMips64EL) {
    410     setSymbolAndType(s, getType(IsMips64EL), IsMips64EL);
    411   }
    412   void setType(unsigned char t, bool IsMips64EL) {
    413     setSymbolAndType(getSymbol(IsMips64EL), t, IsMips64EL);
    414   }
    415   void setSymbolAndType(uint32_t s, unsigned char t, bool IsMips64EL) {
    416     this->setRInfo((s << 8) + t, IsMips64EL);
    417   }
    418 };
    419 
    420 template <endianness TargetEndianness>
    421 struct Elf_Rel_Impl<ELFType<TargetEndianness, false>, true>
    422     : public Elf_Rel_Impl<ELFType<TargetEndianness, false>, false> {
    423   LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
    424   static const bool IsRela = true;
    425   Elf_Sword r_addend; // Compute value for relocatable field by adding this
    426 };
    427 
    428 template <endianness TargetEndianness>
    429 struct Elf_Rel_Impl<ELFType<TargetEndianness, true>, false> {
    430   LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
    431   static const bool IsRela = false;
    432   Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
    433   Elf_Xword r_info;  // Symbol table index and type of relocation to apply
    434 
    435   uint64_t getRInfo(bool isMips64EL) const {
    436     uint64_t t = r_info;
    437     if (!isMips64EL)
    438       return t;
    439     // Mips64 little endian has a "special" encoding of r_info. Instead of one
    440     // 64 bit little endian number, it is a little endian 32 bit number followed
    441     // by a 32 bit big endian number.
    442     return (t << 32) | ((t >> 8) & 0xff000000) | ((t >> 24) & 0x00ff0000) |
    443            ((t >> 40) & 0x0000ff00) | ((t >> 56) & 0x000000ff);
    444   }
    445 
    446   void setRInfo(uint64_t R, bool IsMips64EL) {
    447     if (IsMips64EL)
    448       r_info = (R >> 32) | ((R & 0xff000000) << 8) | ((R & 0x00ff0000) << 24) |
    449                ((R & 0x0000ff00) << 40) | ((R & 0x000000ff) << 56);
    450     else
    451       r_info = R;
    452   }
    453 
    454   // These accessors and mutators correspond to the ELF64_R_SYM, ELF64_R_TYPE,
    455   // and ELF64_R_INFO macros defined in the ELF specification:
    456   uint32_t getSymbol(bool isMips64EL) const {
    457     return (uint32_t)(this->getRInfo(isMips64EL) >> 32);
    458   }
    459   uint32_t getType(bool isMips64EL) const {
    460     return (uint32_t)(this->getRInfo(isMips64EL) & 0xffffffffL);
    461   }
    462   void setSymbol(uint32_t s, bool IsMips64EL) {
    463     setSymbolAndType(s, getType(IsMips64EL), IsMips64EL);
    464   }
    465   void setType(uint32_t t, bool IsMips64EL) {
    466     setSymbolAndType(getSymbol(IsMips64EL), t, IsMips64EL);
    467   }
    468   void setSymbolAndType(uint32_t s, uint32_t t, bool IsMips64EL) {
    469     this->setRInfo(((uint64_t)s << 32) + (t & 0xffffffffL), IsMips64EL);
    470   }
    471 };
    472 
    473 template <endianness TargetEndianness>
    474 struct Elf_Rel_Impl<ELFType<TargetEndianness, true>, true>
    475     : public Elf_Rel_Impl<ELFType<TargetEndianness, true>, false> {
    476   LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
    477   static const bool IsRela = true;
    478   Elf_Sxword r_addend; // Compute value for relocatable field by adding this.
    479 };
    480 
    481 template <class ELFT>
    482 struct Elf_Ehdr_Impl {
    483   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
    484   unsigned char e_ident[ELF::EI_NIDENT]; // ELF Identification bytes
    485   Elf_Half e_type;                       // Type of file (see ET_*)
    486   Elf_Half e_machine;   // Required architecture for this file (see EM_*)
    487   Elf_Word e_version;   // Must be equal to 1
    488   Elf_Addr e_entry;     // Address to jump to in order to start program
    489   Elf_Off e_phoff;      // Program header table's file offset, in bytes
    490   Elf_Off e_shoff;      // Section header table's file offset, in bytes
    491   Elf_Word e_flags;     // Processor-specific flags
    492   Elf_Half e_ehsize;    // Size of ELF header, in bytes
    493   Elf_Half e_phentsize; // Size of an entry in the program header table
    494   Elf_Half e_phnum;     // Number of entries in the program header table
    495   Elf_Half e_shentsize; // Size of an entry in the section header table
    496   Elf_Half e_shnum;     // Number of entries in the section header table
    497   Elf_Half e_shstrndx;  // Section header table index of section name
    498                         // string table
    499 
    500   bool checkMagic() const {
    501     return (memcmp(e_ident, ELF::ElfMagic, strlen(ELF::ElfMagic))) == 0;
    502   }
    503 
    504   unsigned char getFileClass() const { return e_ident[ELF::EI_CLASS]; }
    505   unsigned char getDataEncoding() const { return e_ident[ELF::EI_DATA]; }
    506 };
    507 
    508 template <endianness TargetEndianness>
    509 struct Elf_Phdr_Impl<ELFType<TargetEndianness, false>> {
    510   LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
    511   Elf_Word p_type;   // Type of segment
    512   Elf_Off p_offset;  // FileOffset where segment is located, in bytes
    513   Elf_Addr p_vaddr;  // Virtual Address of beginning of segment
    514   Elf_Addr p_paddr;  // Physical address of beginning of segment (OS-specific)
    515   Elf_Word p_filesz; // Num. of bytes in file image of segment (may be zero)
    516   Elf_Word p_memsz;  // Num. of bytes in mem image of segment (may be zero)
    517   Elf_Word p_flags;  // Segment flags
    518   Elf_Word p_align;  // Segment alignment constraint
    519 };
    520 
    521 template <endianness TargetEndianness>
    522 struct Elf_Phdr_Impl<ELFType<TargetEndianness, true>> {
    523   LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
    524   Elf_Word p_type;    // Type of segment
    525   Elf_Word p_flags;   // Segment flags
    526   Elf_Off p_offset;   // FileOffset where segment is located, in bytes
    527   Elf_Addr p_vaddr;   // Virtual Address of beginning of segment
    528   Elf_Addr p_paddr;   // Physical address of beginning of segment (OS-specific)
    529   Elf_Xword p_filesz; // Num. of bytes in file image of segment (may be zero)
    530   Elf_Xword p_memsz;  // Num. of bytes in mem image of segment (may be zero)
    531   Elf_Xword p_align;  // Segment alignment constraint
    532 };
    533 
    534 // ELFT needed for endianness.
    535 template <class ELFT>
    536 struct Elf_Hash_Impl {
    537   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
    538   Elf_Word nbucket;
    539   Elf_Word nchain;
    540 
    541   ArrayRef<Elf_Word> buckets() const {
    542     return ArrayRef<Elf_Word>(&nbucket + 2, &nbucket + 2 + nbucket);
    543   }
    544 
    545   ArrayRef<Elf_Word> chains() const {
    546     return ArrayRef<Elf_Word>(&nbucket + 2 + nbucket,
    547                               &nbucket + 2 + nbucket + nchain);
    548   }
    549 };
    550 
    551 // .gnu.hash section
    552 template <class ELFT>
    553 struct Elf_GnuHash_Impl {
    554   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
    555   Elf_Word nbuckets;
    556   Elf_Word symndx;
    557   Elf_Word maskwords;
    558   Elf_Word shift2;
    559 
    560   ArrayRef<Elf_Off> filter() const {
    561     return ArrayRef<Elf_Off>(reinterpret_cast<const Elf_Off *>(&shift2 + 1),
    562                              maskwords);
    563   }
    564 
    565   ArrayRef<Elf_Word> buckets() const {
    566     return ArrayRef<Elf_Word>(
    567         reinterpret_cast<const Elf_Word *>(filter().end()), nbuckets);
    568   }
    569 
    570   ArrayRef<Elf_Word> values(unsigned DynamicSymCount) const {
    571     assert(DynamicSymCount >= symndx);
    572     return ArrayRef<Elf_Word>(buckets().end(), DynamicSymCount - symndx);
    573   }
    574 };
    575 
    576 // Compressed section headers.
    577 // http://www.sco.com/developers/gabi/latest/ch4.sheader.html#compression_header
    578 template <endianness TargetEndianness>
    579 struct Elf_Chdr_Impl<ELFType<TargetEndianness, false>> {
    580   LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
    581   Elf_Word ch_type;
    582   Elf_Word ch_size;
    583   Elf_Word ch_addralign;
    584 };
    585 
    586 template <endianness TargetEndianness>
    587 struct Elf_Chdr_Impl<ELFType<TargetEndianness, true>> {
    588   LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
    589   Elf_Word ch_type;
    590   Elf_Word ch_reserved;
    591   Elf_Xword ch_size;
    592   Elf_Xword ch_addralign;
    593 };
    594 
    595 /// Note header
    596 template <class ELFT>
    597 struct Elf_Nhdr_Impl {
    598   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
    599   Elf_Word n_namesz;
    600   Elf_Word n_descsz;
    601   Elf_Word n_type;
    602 
    603   /// The alignment of the name and descriptor.
    604   ///
    605   /// Implementations differ from the specification here: in practice all
    606   /// variants align both the name and descriptor to 4-bytes.
    607   static const unsigned int Align = 4;
    608 
    609   /// Get the size of the note, including name, descriptor, and padding.
    610   size_t getSize() const {
    611     return sizeof(*this) + alignTo<Align>(n_namesz) + alignTo<Align>(n_descsz);
    612   }
    613 };
    614 
    615 /// An ELF note.
    616 ///
    617 /// Wraps a note header, providing methods for accessing the name and
    618 /// descriptor safely.
    619 template <class ELFT>
    620 class Elf_Note_Impl {
    621   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
    622 
    623   const Elf_Nhdr_Impl<ELFT> &Nhdr;
    624 
    625   template <class NoteIteratorELFT> friend class Elf_Note_Iterator_Impl;
    626 
    627 public:
    628   Elf_Note_Impl(const Elf_Nhdr_Impl<ELFT> &Nhdr) : Nhdr(Nhdr) {}
    629 
    630   /// Get the note's name, excluding the terminating null byte.
    631   StringRef getName() const {
    632     if (!Nhdr.n_namesz)
    633       return StringRef();
    634     return StringRef(reinterpret_cast<const char *>(&Nhdr) + sizeof(Nhdr),
    635                      Nhdr.n_namesz - 1);
    636   }
    637 
    638   /// Get the note's descriptor.
    639   ArrayRef<uint8_t> getDesc() const {
    640     if (!Nhdr.n_descsz)
    641       return ArrayRef<uint8_t>();
    642     return ArrayRef<uint8_t>(
    643         reinterpret_cast<const uint8_t *>(&Nhdr) + sizeof(Nhdr) +
    644           alignTo<Elf_Nhdr_Impl<ELFT>::Align>(Nhdr.n_namesz),
    645         Nhdr.n_descsz);
    646   }
    647 
    648   /// Get the note's descriptor as StringRef
    649   StringRef getDescAsStringRef() const {
    650     ArrayRef<uint8_t> Desc = getDesc();
    651     return StringRef(reinterpret_cast<const char *>(Desc.data()), Desc.size());
    652   }
    653 
    654   /// Get the note's type.
    655   Elf_Word getType() const { return Nhdr.n_type; }
    656 };
    657 
    658 template <class ELFT> class Elf_Note_Iterator_Impl {
    659 public:
    660   using iterator_category = std::forward_iterator_tag;
    661   using value_type = Elf_Note_Impl<ELFT>;
    662   using difference_type = std::ptrdiff_t;
    663   using pointer = value_type *;
    664   using reference = value_type &;
    665 
    666 private:
    667   // Nhdr being a nullptr marks the end of iteration.
    668   const Elf_Nhdr_Impl<ELFT> *Nhdr = nullptr;
    669   size_t RemainingSize = 0u;
    670   Error *Err = nullptr;
    671 
    672   template <class ELFFileELFT> friend class ELFFile;
    673 
    674   // Stop iteration and indicate an overflow.
    675   void stopWithOverflowError() {
    676     Nhdr = nullptr;
    677     *Err = make_error<StringError>("ELF note overflows container",
    678                                    object_error::parse_failed);
    679   }
    680 
    681   // Advance Nhdr by NoteSize bytes, starting from NhdrPos.
    682   //
    683   // Assumes NoteSize <= RemainingSize. Ensures Nhdr->getSize() <= RemainingSize
    684   // upon returning. Handles stopping iteration when reaching the end of the
    685   // container, either cleanly or with an overflow error.
    686   void advanceNhdr(const uint8_t *NhdrPos, size_t NoteSize) {
    687     RemainingSize -= NoteSize;
    688     if (RemainingSize == 0u) {
    689       // Ensure that if the iterator walks to the end, the error is checked
    690       // afterwards.
    691       *Err = Error::success();
    692       Nhdr = nullptr;
    693     } else if (sizeof(*Nhdr) > RemainingSize)
    694       stopWithOverflowError();
    695     else {
    696       Nhdr = reinterpret_cast<const Elf_Nhdr_Impl<ELFT> *>(NhdrPos + NoteSize);
    697       if (Nhdr->getSize() > RemainingSize)
    698         stopWithOverflowError();
    699       else
    700         *Err = Error::success();
    701     }
    702   }
    703 
    704   Elf_Note_Iterator_Impl() {}
    705   explicit Elf_Note_Iterator_Impl(Error &Err) : Err(&Err) {}
    706   Elf_Note_Iterator_Impl(const uint8_t *Start, size_t Size, Error &Err)
    707       : RemainingSize(Size), Err(&Err) {
    708     consumeError(std::move(Err));
    709     assert(Start && "ELF note iterator starting at NULL");
    710     advanceNhdr(Start, 0u);
    711   }
    712 
    713 public:
    714   Elf_Note_Iterator_Impl &operator++() {
    715     assert(Nhdr && "incremented ELF note end iterator");
    716     const uint8_t *NhdrPos = reinterpret_cast<const uint8_t *>(Nhdr);
    717     size_t NoteSize = Nhdr->getSize();
    718     advanceNhdr(NhdrPos, NoteSize);
    719     return *this;
    720   }
    721   bool operator==(Elf_Note_Iterator_Impl Other) const {
    722     if (!Nhdr && Other.Err)
    723       (void)(bool)(*Other.Err);
    724     if (!Other.Nhdr && Err)
    725       (void)(bool)(*Err);
    726     return Nhdr == Other.Nhdr;
    727   }
    728   bool operator!=(Elf_Note_Iterator_Impl Other) const {
    729     return !(*this == Other);
    730   }
    731   Elf_Note_Impl<ELFT> operator*() const {
    732     assert(Nhdr && "dereferenced ELF note end iterator");
    733     return Elf_Note_Impl<ELFT>(*Nhdr);
    734   }
    735 };
    736 
    737 template <class ELFT> struct Elf_CGProfile_Impl {
    738   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
    739   Elf_Word cgp_from;
    740   Elf_Word cgp_to;
    741   Elf_Xword cgp_weight;
    742 };
    743 
    744 // MIPS .reginfo section
    745 template <class ELFT>
    746 struct Elf_Mips_RegInfo;
    747 
    748 template <support::endianness TargetEndianness>
    749 struct Elf_Mips_RegInfo<ELFType<TargetEndianness, false>> {
    750   LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
    751   Elf_Word ri_gprmask;     // bit-mask of used general registers
    752   Elf_Word ri_cprmask[4];  // bit-mask of used co-processor registers
    753   Elf_Addr ri_gp_value;    // gp register value
    754 };
    755 
    756 template <support::endianness TargetEndianness>
    757 struct Elf_Mips_RegInfo<ELFType<TargetEndianness, true>> {
    758   LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
    759   Elf_Word ri_gprmask;     // bit-mask of used general registers
    760   Elf_Word ri_pad;         // unused padding field
    761   Elf_Word ri_cprmask[4];  // bit-mask of used co-processor registers
    762   Elf_Addr ri_gp_value;    // gp register value
    763 };
    764 
    765 // .MIPS.options section
    766 template <class ELFT> struct Elf_Mips_Options {
    767   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
    768   uint8_t kind;     // Determines interpretation of variable part of descriptor
    769   uint8_t size;     // Byte size of descriptor, including this header
    770   Elf_Half section; // Section header index of section affected,
    771                     // or 0 for global options
    772   Elf_Word info;    // Kind-specific information
    773 
    774   Elf_Mips_RegInfo<ELFT> &getRegInfo() {
    775     assert(kind == ELF::ODK_REGINFO);
    776     return *reinterpret_cast<Elf_Mips_RegInfo<ELFT> *>(
    777         (uint8_t *)this + sizeof(Elf_Mips_Options));
    778   }
    779   const Elf_Mips_RegInfo<ELFT> &getRegInfo() const {
    780     return const_cast<Elf_Mips_Options *>(this)->getRegInfo();
    781   }
    782 };
    783 
    784 // .MIPS.abiflags section content
    785 template <class ELFT> struct Elf_Mips_ABIFlags {
    786   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
    787   Elf_Half version;  // Version of the structure
    788   uint8_t isa_level; // ISA level: 1-5, 32, and 64
    789   uint8_t isa_rev;   // ISA revision (0 for MIPS I - MIPS V)
    790   uint8_t gpr_size;  // General purpose registers size
    791   uint8_t cpr1_size; // Co-processor 1 registers size
    792   uint8_t cpr2_size; // Co-processor 2 registers size
    793   uint8_t fp_abi;    // Floating-point ABI flag
    794   Elf_Word isa_ext;  // Processor-specific extension
    795   Elf_Word ases;     // ASEs flags
    796   Elf_Word flags1;   // General flags
    797   Elf_Word flags2;   // General flags
    798 };
    799 
    800 // Struct representing the BBAddrMap for one function.
    801 template <class ELFT> struct Elf_BBAddrMap_Impl {
    802   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
    803   uintX_t Addr; // Function address
    804   // Struct representing the BBAddrMap information for one basic block.
    805   struct BBEntry {
    806     uint32_t Offset; // Offset of basic block relative to function start.
    807     uint32_t Size;   // Size of the basic block.
    808 
    809     // The following fields are decoded from the Metadata field. The encoding
    810     // happens in AsmPrinter.cpp:getBBAddrMapMetadata.
    811     bool HasReturn;      // If this block ends with a return (or tail call).
    812     bool HasTailCall;    // If this block ends with a tail call.
    813     bool IsEHPad;        // If this is an exception handling block.
    814     bool CanFallThrough; // If this block can fall through to its next.
    815 
    816     BBEntry(uint32_t Offset, uint32_t Size, uint32_t Metadata)
    817         : Offset(Offset), Size(Size), HasReturn(Metadata & 1),
    818           HasTailCall(Metadata & (1 << 1)), IsEHPad(Metadata & (1 << 2)),
    819           CanFallThrough(Metadata & (1 << 3)){};
    820   };
    821   std::vector<BBEntry> BBEntries; // Basic block entries for this function.
    822 };
    823 
    824 } // end namespace object.
    825 } // end namespace llvm.
    826 
    827 #endif // LLVM_OBJECT_ELFTYPES_H
    828