Home | History | Annotate | Download | only in Object
      1 //===- ELF.h - ELF object file implementation -------------------*- 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 // This file declares the ELFFile template class.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #ifndef LLVM_OBJECT_ELF_H
     15 #define LLVM_OBJECT_ELF_H
     16 
     17 #include "llvm/ADT/ArrayRef.h"
     18 #include "llvm/ADT/DenseMap.h"
     19 #include "llvm/ADT/PointerIntPair.h"
     20 #include "llvm/ADT/SmallVector.h"
     21 #include "llvm/ADT/StringSwitch.h"
     22 #include "llvm/ADT/Triple.h"
     23 #include "llvm/Object/ELFTypes.h"
     24 #include "llvm/Object/Error.h"
     25 #include "llvm/Support/Casting.h"
     26 #include "llvm/Support/ELF.h"
     27 #include "llvm/Support/Endian.h"
     28 #include "llvm/Support/ErrorHandling.h"
     29 #include "llvm/Support/ErrorOr.h"
     30 #include "llvm/Support/MemoryBuffer.h"
     31 #include "llvm/Support/raw_ostream.h"
     32 #include <algorithm>
     33 #include <limits>
     34 #include <utility>
     35 
     36 namespace llvm {
     37 namespace object {
     38 
     39 StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type);
     40 
     41 // Subclasses of ELFFile may need this for template instantiation
     42 inline std::pair<unsigned char, unsigned char>
     43 getElfArchType(StringRef Object) {
     44   if (Object.size() < ELF::EI_NIDENT)
     45     return std::make_pair((uint8_t)ELF::ELFCLASSNONE,
     46                           (uint8_t)ELF::ELFDATANONE);
     47   return std::make_pair((uint8_t)Object[ELF::EI_CLASS],
     48                         (uint8_t)Object[ELF::EI_DATA]);
     49 }
     50 
     51 template <class ELFT>
     52 class ELFFile {
     53 public:
     54   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
     55   typedef typename std::conditional<ELFT::Is64Bits,
     56                                     uint64_t, uint32_t>::type uintX_t;
     57 
     58   /// \brief Iterate over constant sized entities.
     59   template <class EntT>
     60   class ELFEntityIterator {
     61   public:
     62     typedef ptrdiff_t difference_type;
     63     typedef EntT value_type;
     64     typedef std::forward_iterator_tag iterator_category;
     65     typedef value_type &reference;
     66     typedef value_type *pointer;
     67 
     68     /// \brief Default construct iterator.
     69     ELFEntityIterator() : EntitySize(0), Current(nullptr) {}
     70     ELFEntityIterator(uintX_t EntSize, const char *Start)
     71         : EntitySize(EntSize), Current(Start) {}
     72 
     73     reference operator *() {
     74       assert(Current && "Attempted to dereference an invalid iterator!");
     75       return *reinterpret_cast<pointer>(Current);
     76     }
     77 
     78     pointer operator ->() {
     79       assert(Current && "Attempted to dereference an invalid iterator!");
     80       return reinterpret_cast<pointer>(Current);
     81     }
     82 
     83     bool operator ==(const ELFEntityIterator &Other) {
     84       return Current == Other.Current;
     85     }
     86 
     87     bool operator !=(const ELFEntityIterator &Other) {
     88       return !(*this == Other);
     89     }
     90 
     91     ELFEntityIterator &operator ++() {
     92       assert(Current && "Attempted to increment an invalid iterator!");
     93       Current += EntitySize;
     94       return *this;
     95     }
     96 
     97     ELFEntityIterator operator ++(int) {
     98       ELFEntityIterator Tmp = *this;
     99       ++*this;
    100       return Tmp;
    101     }
    102 
    103     ELFEntityIterator &operator =(const ELFEntityIterator &Other) {
    104       EntitySize = Other.EntitySize;
    105       Current = Other.Current;
    106       return *this;
    107     }
    108 
    109     difference_type operator -(const ELFEntityIterator &Other) const {
    110       assert(EntitySize == Other.EntitySize &&
    111              "Subtracting iterators of different EntitySize!");
    112       return (Current - Other.Current) / EntitySize;
    113     }
    114 
    115     const char *get() const { return Current; }
    116 
    117     uintX_t getEntSize() const { return EntitySize; }
    118 
    119   private:
    120     uintX_t EntitySize;
    121     const char *Current;
    122   };
    123 
    124   typedef Elf_Ehdr_Impl<ELFT> Elf_Ehdr;
    125   typedef Elf_Shdr_Impl<ELFT> Elf_Shdr;
    126   typedef Elf_Sym_Impl<ELFT> Elf_Sym;
    127   typedef Elf_Dyn_Impl<ELFT> Elf_Dyn;
    128   typedef Elf_Phdr_Impl<ELFT> Elf_Phdr;
    129   typedef Elf_Rel_Impl<ELFT, false> Elf_Rel;
    130   typedef Elf_Rel_Impl<ELFT, true> Elf_Rela;
    131   typedef Elf_Verdef_Impl<ELFT> Elf_Verdef;
    132   typedef Elf_Verdaux_Impl<ELFT> Elf_Verdaux;
    133   typedef Elf_Verneed_Impl<ELFT> Elf_Verneed;
    134   typedef Elf_Vernaux_Impl<ELFT> Elf_Vernaux;
    135   typedef Elf_Versym_Impl<ELFT> Elf_Versym;
    136   typedef ELFEntityIterator<const Elf_Dyn> Elf_Dyn_Iter;
    137   typedef iterator_range<Elf_Dyn_Iter> Elf_Dyn_Range;
    138   typedef ELFEntityIterator<const Elf_Rela> Elf_Rela_Iter;
    139   typedef ELFEntityIterator<const Elf_Rel> Elf_Rel_Iter;
    140   typedef ELFEntityIterator<const Elf_Shdr> Elf_Shdr_Iter;
    141   typedef iterator_range<Elf_Shdr_Iter> Elf_Shdr_Range;
    142 
    143   /// \brief Archive files are 2 byte aligned, so we need this for
    144   ///     PointerIntPair to work.
    145   template <typename T>
    146   class ArchivePointerTypeTraits {
    147   public:
    148     static inline const void *getAsVoidPointer(T *P) { return P; }
    149     static inline T *getFromVoidPointer(const void *P) {
    150       return static_cast<T *>(P);
    151     }
    152     enum { NumLowBitsAvailable = 1 };
    153   };
    154 
    155   class Elf_Sym_Iter {
    156   public:
    157     typedef ptrdiff_t difference_type;
    158     typedef const Elf_Sym value_type;
    159     typedef std::random_access_iterator_tag iterator_category;
    160     typedef value_type &reference;
    161     typedef value_type *pointer;
    162 
    163     /// \brief Default construct iterator.
    164     Elf_Sym_Iter() : EntitySize(0), Current(0, false) {}
    165     Elf_Sym_Iter(uintX_t EntSize, const char *Start, bool IsDynamic)
    166         : EntitySize(EntSize), Current(Start, IsDynamic) {}
    167 
    168     reference operator*() {
    169       assert(Current.getPointer() &&
    170              "Attempted to dereference an invalid iterator!");
    171       return *reinterpret_cast<pointer>(Current.getPointer());
    172     }
    173 
    174     pointer operator->() {
    175       assert(Current.getPointer() &&
    176              "Attempted to dereference an invalid iterator!");
    177       return reinterpret_cast<pointer>(Current.getPointer());
    178     }
    179 
    180     bool operator==(const Elf_Sym_Iter &Other) {
    181       return Current == Other.Current;
    182     }
    183 
    184     bool operator!=(const Elf_Sym_Iter &Other) { return !(*this == Other); }
    185 
    186     Elf_Sym_Iter &operator++() {
    187       assert(Current.getPointer() &&
    188              "Attempted to increment an invalid iterator!");
    189       Current.setPointer(Current.getPointer() + EntitySize);
    190       return *this;
    191     }
    192 
    193     Elf_Sym_Iter operator++(int) {
    194       Elf_Sym_Iter Tmp = *this;
    195       ++*this;
    196       return Tmp;
    197     }
    198 
    199     Elf_Sym_Iter operator+(difference_type Dist) {
    200       assert(Current.getPointer() &&
    201              "Attempted to increment an invalid iterator!");
    202       Current.setPointer(Current.getPointer() + EntitySize * Dist);
    203       return *this;
    204     }
    205 
    206     Elf_Sym_Iter &operator=(const Elf_Sym_Iter &Other) {
    207       EntitySize = Other.EntitySize;
    208       Current = Other.Current;
    209       return *this;
    210     }
    211 
    212     difference_type operator-(const Elf_Sym_Iter &Other) const {
    213       assert(EntitySize == Other.EntitySize &&
    214              "Subtracting iterators of different EntitySize!");
    215       return (Current.getPointer() - Other.Current.getPointer()) / EntitySize;
    216     }
    217 
    218     const char *get() const { return Current.getPointer(); }
    219 
    220     bool isDynamic() const { return Current.getInt(); }
    221 
    222     uintX_t getEntSize() const { return EntitySize; }
    223 
    224   private:
    225     uintX_t EntitySize;
    226     PointerIntPair<const char *, 1, bool,
    227                    ArchivePointerTypeTraits<const char> > Current;
    228   };
    229 
    230 private:
    231   typedef SmallVector<const Elf_Shdr *, 2> Sections_t;
    232   typedef DenseMap<unsigned, unsigned> IndexMap_t;
    233 
    234   StringRef Buf;
    235 
    236   const uint8_t *base() const {
    237     return reinterpret_cast<const uint8_t *>(Buf.data());
    238   }
    239 
    240   const Elf_Ehdr *Header;
    241   const Elf_Shdr *SectionHeaderTable;
    242   const Elf_Shdr *dot_shstrtab_sec; // Section header string table.
    243   const Elf_Shdr *dot_strtab_sec;   // Symbol header string table.
    244   const Elf_Shdr *dot_symtab_sec;   // Symbol table section.
    245 
    246   const Elf_Shdr *SymbolTableSectionHeaderIndex;
    247   DenseMap<const Elf_Sym *, ELF::Elf64_Word> ExtendedSymbolTable;
    248 
    249   const Elf_Shdr *dot_gnu_version_sec;   // .gnu.version
    250   const Elf_Shdr *dot_gnu_version_r_sec; // .gnu.version_r
    251   const Elf_Shdr *dot_gnu_version_d_sec; // .gnu.version_d
    252 
    253   /// \brief Represents a region described by entries in the .dynamic table.
    254   struct DynRegionInfo {
    255     DynRegionInfo() : Addr(nullptr), Size(0), EntSize(0) {}
    256     /// \brief Address in current address space.
    257     const void *Addr;
    258     /// \brief Size in bytes of the region.
    259     uintX_t Size;
    260     /// \brief Size of each entity in the region.
    261     uintX_t EntSize;
    262   };
    263 
    264   DynRegionInfo DynamicRegion;
    265   DynRegionInfo DynHashRegion;
    266   DynRegionInfo DynStrRegion;
    267   DynRegionInfo DynSymRegion;
    268 
    269   // Pointer to SONAME entry in dynamic string table
    270   // This is set the first time getLoadName is called.
    271   mutable const char *dt_soname;
    272 
    273   // Records for each version index the corresponding Verdef or Vernaux entry.
    274   // This is filled the first time LoadVersionMap() is called.
    275   class VersionMapEntry : public PointerIntPair<const void*, 1> {
    276     public:
    277     // If the integer is 0, this is an Elf_Verdef*.
    278     // If the integer is 1, this is an Elf_Vernaux*.
    279     VersionMapEntry() : PointerIntPair<const void*, 1>(nullptr, 0) { }
    280     VersionMapEntry(const Elf_Verdef *verdef)
    281         : PointerIntPair<const void*, 1>(verdef, 0) { }
    282     VersionMapEntry(const Elf_Vernaux *vernaux)
    283         : PointerIntPair<const void*, 1>(vernaux, 1) { }
    284     bool isNull() const { return getPointer() == nullptr; }
    285     bool isVerdef() const { return !isNull() && getInt() == 0; }
    286     bool isVernaux() const { return !isNull() && getInt() == 1; }
    287     const Elf_Verdef *getVerdef() const {
    288       return isVerdef() ? (const Elf_Verdef*)getPointer() : nullptr;
    289     }
    290     const Elf_Vernaux *getVernaux() const {
    291       return isVernaux() ? (const Elf_Vernaux*)getPointer() : nullptr;
    292     }
    293   };
    294   mutable SmallVector<VersionMapEntry, 16> VersionMap;
    295   void LoadVersionDefs(const Elf_Shdr *sec) const;
    296   void LoadVersionNeeds(const Elf_Shdr *ec) const;
    297   void LoadVersionMap() const;
    298 
    299 public:
    300   template<typename T>
    301   const T        *getEntry(uint32_t Section, uint32_t Entry) const;
    302   template <typename T>
    303   const T *getEntry(const Elf_Shdr *Section, uint32_t Entry) const;
    304   const char     *getString(uint32_t section, uint32_t offset) const;
    305   const char     *getString(const Elf_Shdr *section, uint32_t offset) const;
    306   const char *getDynamicString(uintX_t Offset) const;
    307   ErrorOr<StringRef> getSymbolVersion(const Elf_Shdr *section,
    308                                       const Elf_Sym *Symb,
    309                                       bool &IsDefault) const;
    310   void VerifyStrTab(const Elf_Shdr *sh) const;
    311 
    312   StringRef getRelocationTypeName(uint32_t Type) const;
    313   void getRelocationTypeName(uint32_t Type,
    314                              SmallVectorImpl<char> &Result) const;
    315 
    316   /// \brief Get the symbol table section and symbol for a given relocation.
    317   template <class RelT>
    318   std::pair<const Elf_Shdr *, const Elf_Sym *>
    319   getRelocationSymbol(const Elf_Shdr *RelSec, const RelT *Rel) const;
    320 
    321   ELFFile(StringRef Object, std::error_code &ec);
    322 
    323   bool isMipsELF64() const {
    324     return Header->e_machine == ELF::EM_MIPS &&
    325       Header->getFileClass() == ELF::ELFCLASS64;
    326   }
    327 
    328   bool isMips64EL() const {
    329     return Header->e_machine == ELF::EM_MIPS &&
    330       Header->getFileClass() == ELF::ELFCLASS64 &&
    331       Header->getDataEncoding() == ELF::ELFDATA2LSB;
    332   }
    333 
    334   Elf_Shdr_Iter begin_sections() const;
    335   Elf_Shdr_Iter end_sections() const;
    336   Elf_Shdr_Range sections() const {
    337     return make_range(begin_sections(), end_sections());
    338   }
    339 
    340   Elf_Sym_Iter begin_symbols() const;
    341   Elf_Sym_Iter end_symbols() const;
    342 
    343   Elf_Dyn_Iter begin_dynamic_table() const;
    344   /// \param NULLEnd use one past the first DT_NULL entry as the end instead of
    345   /// the section size.
    346   Elf_Dyn_Iter end_dynamic_table(bool NULLEnd = false) const;
    347   Elf_Dyn_Range dynamic_table(bool NULLEnd = false) const {
    348     return make_range(begin_dynamic_table(), end_dynamic_table(NULLEnd));
    349   }
    350 
    351   Elf_Sym_Iter begin_dynamic_symbols() const {
    352     if (DynSymRegion.Addr)
    353       return Elf_Sym_Iter(DynSymRegion.EntSize, (const char *)DynSymRegion.Addr,
    354                           true);
    355     return Elf_Sym_Iter(0, nullptr, true);
    356   }
    357 
    358   Elf_Sym_Iter end_dynamic_symbols() const {
    359     if (DynSymRegion.Addr)
    360       return Elf_Sym_Iter(DynSymRegion.EntSize,
    361                           (const char *)DynSymRegion.Addr + DynSymRegion.Size,
    362                           true);
    363     return Elf_Sym_Iter(0, nullptr, true);
    364   }
    365 
    366   Elf_Rela_Iter begin_rela(const Elf_Shdr *sec) const {
    367     return Elf_Rela_Iter(sec->sh_entsize,
    368                          (const char *)(base() + sec->sh_offset));
    369   }
    370 
    371   Elf_Rela_Iter end_rela(const Elf_Shdr *sec) const {
    372     return Elf_Rela_Iter(
    373         sec->sh_entsize,
    374         (const char *)(base() + sec->sh_offset + sec->sh_size));
    375   }
    376 
    377   Elf_Rel_Iter begin_rel(const Elf_Shdr *sec) const {
    378     return Elf_Rel_Iter(sec->sh_entsize,
    379                         (const char *)(base() + sec->sh_offset));
    380   }
    381 
    382   Elf_Rel_Iter end_rel(const Elf_Shdr *sec) const {
    383     return Elf_Rel_Iter(sec->sh_entsize,
    384                         (const char *)(base() + sec->sh_offset + sec->sh_size));
    385   }
    386 
    387   /// \brief Iterate over program header table.
    388   typedef ELFEntityIterator<const Elf_Phdr> Elf_Phdr_Iter;
    389 
    390   Elf_Phdr_Iter begin_program_headers() const {
    391     return Elf_Phdr_Iter(Header->e_phentsize,
    392                          (const char*)base() + Header->e_phoff);
    393   }
    394 
    395   Elf_Phdr_Iter end_program_headers() const {
    396     return Elf_Phdr_Iter(Header->e_phentsize,
    397                          (const char*)base() +
    398                            Header->e_phoff +
    399                            (Header->e_phnum * Header->e_phentsize));
    400   }
    401 
    402   uint64_t getNumSections() const;
    403   uintX_t getStringTableIndex() const;
    404   ELF::Elf64_Word getSymbolTableIndex(const Elf_Sym *symb) const;
    405   const Elf_Ehdr *getHeader() const { return Header; }
    406   const Elf_Shdr *getSection(const Elf_Sym *symb) const;
    407   const Elf_Shdr *getSection(uint32_t Index) const;
    408   const Elf_Sym *getSymbol(uint32_t index) const;
    409 
    410   ErrorOr<StringRef> getSymbolName(Elf_Sym_Iter Sym) const;
    411 
    412   /// \brief Get the name of \p Symb.
    413   /// \param SymTab The symbol table section \p Symb is contained in.
    414   /// \param Symb The symbol to get the name of.
    415   ///
    416   /// \p SymTab is used to lookup the string table to use to get the symbol's
    417   /// name.
    418   ErrorOr<StringRef> getSymbolName(const Elf_Shdr *SymTab,
    419                                    const Elf_Sym *Symb) const;
    420   ErrorOr<StringRef> getSectionName(const Elf_Shdr *Section) const;
    421   uint64_t getSymbolIndex(const Elf_Sym *sym) const;
    422   ErrorOr<ArrayRef<uint8_t> > getSectionContents(const Elf_Shdr *Sec) const;
    423   StringRef getLoadName() const;
    424 };
    425 
    426 // Use an alignment of 2 for the typedefs since that is the worst case for
    427 // ELF files in archives.
    428 typedef ELFFile<ELFType<support::little, 2, false> > ELF32LEFile;
    429 typedef ELFFile<ELFType<support::little, 2, true> > ELF64LEFile;
    430 typedef ELFFile<ELFType<support::big, 2, false> > ELF32BEFile;
    431 typedef ELFFile<ELFType<support::big, 2, true> > ELF64BEFile;
    432 
    433 // Iterate through the version definitions, and place each Elf_Verdef
    434 // in the VersionMap according to its index.
    435 template <class ELFT>
    436 void ELFFile<ELFT>::LoadVersionDefs(const Elf_Shdr *sec) const {
    437   unsigned vd_size = sec->sh_size;  // Size of section in bytes
    438   unsigned vd_count = sec->sh_info; // Number of Verdef entries
    439   const char *sec_start = (const char*)base() + sec->sh_offset;
    440   const char *sec_end = sec_start + vd_size;
    441   // The first Verdef entry is at the start of the section.
    442   const char *p = sec_start;
    443   for (unsigned i = 0; i < vd_count; i++) {
    444     if (p + sizeof(Elf_Verdef) > sec_end)
    445       report_fatal_error("Section ended unexpectedly while scanning "
    446                          "version definitions.");
    447     const Elf_Verdef *vd = reinterpret_cast<const Elf_Verdef *>(p);
    448     if (vd->vd_version != ELF::VER_DEF_CURRENT)
    449       report_fatal_error("Unexpected verdef version");
    450     size_t index = vd->vd_ndx & ELF::VERSYM_VERSION;
    451     if (index >= VersionMap.size())
    452       VersionMap.resize(index + 1);
    453     VersionMap[index] = VersionMapEntry(vd);
    454     p += vd->vd_next;
    455   }
    456 }
    457 
    458 // Iterate through the versions needed section, and place each Elf_Vernaux
    459 // in the VersionMap according to its index.
    460 template <class ELFT>
    461 void ELFFile<ELFT>::LoadVersionNeeds(const Elf_Shdr *sec) const {
    462   unsigned vn_size = sec->sh_size;  // Size of section in bytes
    463   unsigned vn_count = sec->sh_info; // Number of Verneed entries
    464   const char *sec_start = (const char *)base() + sec->sh_offset;
    465   const char *sec_end = sec_start + vn_size;
    466   // The first Verneed entry is at the start of the section.
    467   const char *p = sec_start;
    468   for (unsigned i = 0; i < vn_count; i++) {
    469     if (p + sizeof(Elf_Verneed) > sec_end)
    470       report_fatal_error("Section ended unexpectedly while scanning "
    471                          "version needed records.");
    472     const Elf_Verneed *vn = reinterpret_cast<const Elf_Verneed *>(p);
    473     if (vn->vn_version != ELF::VER_NEED_CURRENT)
    474       report_fatal_error("Unexpected verneed version");
    475     // Iterate through the Vernaux entries
    476     const char *paux = p + vn->vn_aux;
    477     for (unsigned j = 0; j < vn->vn_cnt; j++) {
    478       if (paux + sizeof(Elf_Vernaux) > sec_end)
    479         report_fatal_error("Section ended unexpected while scanning auxiliary "
    480                            "version needed records.");
    481       const Elf_Vernaux *vna = reinterpret_cast<const Elf_Vernaux *>(paux);
    482       size_t index = vna->vna_other & ELF::VERSYM_VERSION;
    483       if (index >= VersionMap.size())
    484         VersionMap.resize(index + 1);
    485       VersionMap[index] = VersionMapEntry(vna);
    486       paux += vna->vna_next;
    487     }
    488     p += vn->vn_next;
    489   }
    490 }
    491 
    492 template <class ELFT>
    493 void ELFFile<ELFT>::LoadVersionMap() const {
    494   // If there is no dynamic symtab or version table, there is nothing to do.
    495   if (!DynSymRegion.Addr || !dot_gnu_version_sec)
    496     return;
    497 
    498   // Has the VersionMap already been loaded?
    499   if (VersionMap.size() > 0)
    500     return;
    501 
    502   // The first two version indexes are reserved.
    503   // Index 0 is LOCAL, index 1 is GLOBAL.
    504   VersionMap.push_back(VersionMapEntry());
    505   VersionMap.push_back(VersionMapEntry());
    506 
    507   if (dot_gnu_version_d_sec)
    508     LoadVersionDefs(dot_gnu_version_d_sec);
    509 
    510   if (dot_gnu_version_r_sec)
    511     LoadVersionNeeds(dot_gnu_version_r_sec);
    512 }
    513 
    514 template <class ELFT>
    515 ELF::Elf64_Word ELFFile<ELFT>::getSymbolTableIndex(const Elf_Sym *symb) const {
    516   if (symb->st_shndx == ELF::SHN_XINDEX)
    517     return ExtendedSymbolTable.lookup(symb);
    518   return symb->st_shndx;
    519 }
    520 
    521 template <class ELFT>
    522 const typename ELFFile<ELFT>::Elf_Shdr *
    523 ELFFile<ELFT>::getSection(const Elf_Sym *symb) const {
    524   if (symb->st_shndx == ELF::SHN_XINDEX)
    525     return getSection(ExtendedSymbolTable.lookup(symb));
    526   if (symb->st_shndx >= ELF::SHN_LORESERVE)
    527     return nullptr;
    528   return getSection(symb->st_shndx);
    529 }
    530 
    531 template <class ELFT>
    532 const typename ELFFile<ELFT>::Elf_Sym *
    533 ELFFile<ELFT>::getSymbol(uint32_t Index) const {
    534   return &*(begin_symbols() + Index);
    535 }
    536 
    537 template <class ELFT>
    538 ErrorOr<ArrayRef<uint8_t> >
    539 ELFFile<ELFT>::getSectionContents(const Elf_Shdr *Sec) const {
    540   if (Sec->sh_offset + Sec->sh_size > Buf.size())
    541     return object_error::parse_failed;
    542   const uint8_t *Start = base() + Sec->sh_offset;
    543   return ArrayRef<uint8_t>(Start, Sec->sh_size);
    544 }
    545 
    546 template <class ELFT>
    547 StringRef ELFFile<ELFT>::getRelocationTypeName(uint32_t Type) const {
    548   return getELFRelocationTypeName(Header->e_machine, Type);
    549 }
    550 
    551 template <class ELFT>
    552 void ELFFile<ELFT>::getRelocationTypeName(uint32_t Type,
    553                                           SmallVectorImpl<char> &Result) const {
    554   if (!isMipsELF64()) {
    555     StringRef Name = getRelocationTypeName(Type);
    556     Result.append(Name.begin(), Name.end());
    557   } else {
    558     // The Mips N64 ABI allows up to three operations to be specified per
    559     // relocation record. Unfortunately there's no easy way to test for the
    560     // presence of N64 ELFs as they have no special flag that identifies them
    561     // as being N64. We can safely assume at the moment that all Mips
    562     // ELFCLASS64 ELFs are N64. New Mips64 ABIs should provide enough
    563     // information to disambiguate between old vs new ABIs.
    564     uint8_t Type1 = (Type >> 0) & 0xFF;
    565     uint8_t Type2 = (Type >> 8) & 0xFF;
    566     uint8_t Type3 = (Type >> 16) & 0xFF;
    567 
    568     // Concat all three relocation type names.
    569     StringRef Name = getRelocationTypeName(Type1);
    570     Result.append(Name.begin(), Name.end());
    571 
    572     Name = getRelocationTypeName(Type2);
    573     Result.append(1, '/');
    574     Result.append(Name.begin(), Name.end());
    575 
    576     Name = getRelocationTypeName(Type3);
    577     Result.append(1, '/');
    578     Result.append(Name.begin(), Name.end());
    579   }
    580 }
    581 
    582 template <class ELFT>
    583 template <class RelT>
    584 std::pair<const typename ELFFile<ELFT>::Elf_Shdr *,
    585           const typename ELFFile<ELFT>::Elf_Sym *>
    586 ELFFile<ELFT>::getRelocationSymbol(const Elf_Shdr *Sec, const RelT *Rel) const {
    587   if (!Sec->sh_link)
    588     return std::make_pair(nullptr, nullptr);
    589   const Elf_Shdr *SymTable = getSection(Sec->sh_link);
    590   return std::make_pair(
    591       SymTable, getEntry<Elf_Sym>(SymTable, Rel->getSymbol(isMips64EL())));
    592 }
    593 
    594 // Verify that the last byte in the string table in a null.
    595 template <class ELFT>
    596 void ELFFile<ELFT>::VerifyStrTab(const Elf_Shdr *sh) const {
    597   const char *strtab = (const char *)base() + sh->sh_offset;
    598   if (strtab[sh->sh_size - 1] != 0)
    599     // FIXME: Proper error handling.
    600     report_fatal_error("String table must end with a null terminator!");
    601 }
    602 
    603 template <class ELFT>
    604 uint64_t ELFFile<ELFT>::getNumSections() const {
    605   assert(Header && "Header not initialized!");
    606   if (Header->e_shnum == ELF::SHN_UNDEF && Header->e_shoff > 0) {
    607     assert(SectionHeaderTable && "SectionHeaderTable not initialized!");
    608     return SectionHeaderTable->sh_size;
    609   }
    610   return Header->e_shnum;
    611 }
    612 
    613 template <class ELFT>
    614 typename ELFFile<ELFT>::uintX_t ELFFile<ELFT>::getStringTableIndex() const {
    615   if (Header->e_shnum == ELF::SHN_UNDEF) {
    616     if (Header->e_shstrndx == ELF::SHN_HIRESERVE)
    617       return SectionHeaderTable->sh_link;
    618     if (Header->e_shstrndx >= getNumSections())
    619       return 0;
    620   }
    621   return Header->e_shstrndx;
    622 }
    623 
    624 template <class ELFT>
    625 ELFFile<ELFT>::ELFFile(StringRef Object, std::error_code &ec)
    626     : Buf(Object), SectionHeaderTable(nullptr), dot_shstrtab_sec(nullptr),
    627       dot_strtab_sec(nullptr), dot_symtab_sec(nullptr),
    628       SymbolTableSectionHeaderIndex(nullptr), dot_gnu_version_sec(nullptr),
    629       dot_gnu_version_r_sec(nullptr), dot_gnu_version_d_sec(nullptr),
    630       dt_soname(nullptr) {
    631   const uint64_t FileSize = Buf.size();
    632 
    633   if (sizeof(Elf_Ehdr) > FileSize)
    634     // FIXME: Proper error handling.
    635     report_fatal_error("File too short!");
    636 
    637   Header = reinterpret_cast<const Elf_Ehdr *>(base());
    638 
    639   if (Header->e_shoff == 0)
    640     return;
    641 
    642   const uint64_t SectionTableOffset = Header->e_shoff;
    643 
    644   if (SectionTableOffset + sizeof(Elf_Shdr) > FileSize)
    645     // FIXME: Proper error handling.
    646     report_fatal_error("Section header table goes past end of file!");
    647 
    648   // The getNumSections() call below depends on SectionHeaderTable being set.
    649   SectionHeaderTable =
    650     reinterpret_cast<const Elf_Shdr *>(base() + SectionTableOffset);
    651   const uint64_t SectionTableSize = getNumSections() * Header->e_shentsize;
    652 
    653   if (SectionTableOffset + SectionTableSize > FileSize)
    654     // FIXME: Proper error handling.
    655     report_fatal_error("Section table goes past end of file!");
    656 
    657   // Scan sections for special sections.
    658 
    659   for (const Elf_Shdr &Sec : sections()) {
    660     switch (Sec.sh_type) {
    661     case ELF::SHT_SYMTAB_SHNDX:
    662       if (SymbolTableSectionHeaderIndex)
    663         // FIXME: Proper error handling.
    664         report_fatal_error("More than one .symtab_shndx!");
    665       SymbolTableSectionHeaderIndex = &Sec;
    666       break;
    667     case ELF::SHT_SYMTAB:
    668       if (dot_symtab_sec)
    669         // FIXME: Proper error handling.
    670         report_fatal_error("More than one .symtab!");
    671       dot_symtab_sec = &Sec;
    672       dot_strtab_sec = getSection(Sec.sh_link);
    673       break;
    674     case ELF::SHT_DYNSYM: {
    675       if (DynSymRegion.Addr)
    676         // FIXME: Proper error handling.
    677         report_fatal_error("More than one .dynsym!");
    678       DynSymRegion.Addr = base() + Sec.sh_offset;
    679       DynSymRegion.Size = Sec.sh_size;
    680       DynSymRegion.EntSize = Sec.sh_entsize;
    681       const Elf_Shdr *DynStr = getSection(Sec.sh_link);
    682       DynStrRegion.Addr = base() + DynStr->sh_offset;
    683       DynStrRegion.Size = DynStr->sh_size;
    684       DynStrRegion.EntSize = DynStr->sh_entsize;
    685       break;
    686     }
    687     case ELF::SHT_DYNAMIC:
    688       if (DynamicRegion.Addr)
    689         // FIXME: Proper error handling.
    690         report_fatal_error("More than one .dynamic!");
    691       DynamicRegion.Addr = base() + Sec.sh_offset;
    692       DynamicRegion.Size = Sec.sh_size;
    693       DynamicRegion.EntSize = Sec.sh_entsize;
    694       break;
    695     case ELF::SHT_GNU_versym:
    696       if (dot_gnu_version_sec != nullptr)
    697         // FIXME: Proper error handling.
    698         report_fatal_error("More than one .gnu.version section!");
    699       dot_gnu_version_sec = &Sec;
    700       break;
    701     case ELF::SHT_GNU_verdef:
    702       if (dot_gnu_version_d_sec != nullptr)
    703         // FIXME: Proper error handling.
    704         report_fatal_error("More than one .gnu.version_d section!");
    705       dot_gnu_version_d_sec = &Sec;
    706       break;
    707     case ELF::SHT_GNU_verneed:
    708       if (dot_gnu_version_r_sec != nullptr)
    709         // FIXME: Proper error handling.
    710         report_fatal_error("More than one .gnu.version_r section!");
    711       dot_gnu_version_r_sec = &Sec;
    712       break;
    713     }
    714   }
    715 
    716   // Get string table sections.
    717   dot_shstrtab_sec = getSection(getStringTableIndex());
    718   if (dot_shstrtab_sec) {
    719     // Verify that the last byte in the string table in a null.
    720     VerifyStrTab(dot_shstrtab_sec);
    721   }
    722 
    723   // Build symbol name side-mapping if there is one.
    724   if (SymbolTableSectionHeaderIndex) {
    725     const Elf_Word *ShndxTable = reinterpret_cast<const Elf_Word*>(base() +
    726                                       SymbolTableSectionHeaderIndex->sh_offset);
    727     for (Elf_Sym_Iter SI = begin_symbols(), SE = end_symbols(); SI != SE;
    728          ++SI) {
    729       if (*ShndxTable != ELF::SHN_UNDEF)
    730         ExtendedSymbolTable[&*SI] = *ShndxTable;
    731       ++ShndxTable;
    732     }
    733   }
    734 
    735   // Scan program headers.
    736   for (Elf_Phdr_Iter PhdrI = begin_program_headers(),
    737                      PhdrE = end_program_headers();
    738        PhdrI != PhdrE; ++PhdrI) {
    739     if (PhdrI->p_type == ELF::PT_DYNAMIC) {
    740       DynamicRegion.Addr = base() + PhdrI->p_offset;
    741       DynamicRegion.Size = PhdrI->p_filesz;
    742       DynamicRegion.EntSize = sizeof(Elf_Dyn);
    743       break;
    744     }
    745   }
    746 
    747   ec = std::error_code();
    748 }
    749 
    750 // Get the symbol table index in the symtab section given a symbol
    751 template <class ELFT>
    752 uint64_t ELFFile<ELFT>::getSymbolIndex(const Elf_Sym *Sym) const {
    753   uintptr_t SymLoc = uintptr_t(Sym);
    754   uintptr_t SymTabLoc = uintptr_t(base() + dot_symtab_sec->sh_offset);
    755   assert(SymLoc > SymTabLoc && "Symbol not in symbol table!");
    756   uint64_t SymOffset = SymLoc - SymTabLoc;
    757   assert(SymOffset % dot_symtab_sec->sh_entsize == 0 &&
    758          "Symbol not multiple of symbol size!");
    759   return SymOffset / dot_symtab_sec->sh_entsize;
    760 }
    761 
    762 template <class ELFT>
    763 typename ELFFile<ELFT>::Elf_Shdr_Iter ELFFile<ELFT>::begin_sections() const {
    764   return Elf_Shdr_Iter(Header->e_shentsize,
    765                        (const char *)base() + Header->e_shoff);
    766 }
    767 
    768 template <class ELFT>
    769 typename ELFFile<ELFT>::Elf_Shdr_Iter ELFFile<ELFT>::end_sections() const {
    770   return Elf_Shdr_Iter(Header->e_shentsize,
    771                        (const char *)base() + Header->e_shoff +
    772                            (getNumSections() * Header->e_shentsize));
    773 }
    774 
    775 template <class ELFT>
    776 typename ELFFile<ELFT>::Elf_Sym_Iter ELFFile<ELFT>::begin_symbols() const {
    777   if (!dot_symtab_sec)
    778     return Elf_Sym_Iter(0, nullptr, false);
    779   return Elf_Sym_Iter(dot_symtab_sec->sh_entsize,
    780                       (const char *)base() + dot_symtab_sec->sh_offset, false);
    781 }
    782 
    783 template <class ELFT>
    784 typename ELFFile<ELFT>::Elf_Sym_Iter ELFFile<ELFT>::end_symbols() const {
    785   if (!dot_symtab_sec)
    786     return Elf_Sym_Iter(0, nullptr, false);
    787   return Elf_Sym_Iter(dot_symtab_sec->sh_entsize,
    788                       (const char *)base() + dot_symtab_sec->sh_offset +
    789                           dot_symtab_sec->sh_size,
    790                       false);
    791 }
    792 
    793 template <class ELFT>
    794 typename ELFFile<ELFT>::Elf_Dyn_Iter
    795 ELFFile<ELFT>::begin_dynamic_table() const {
    796   if (DynamicRegion.Addr)
    797     return Elf_Dyn_Iter(DynamicRegion.EntSize,
    798                         (const char *)DynamicRegion.Addr);
    799   return Elf_Dyn_Iter(0, nullptr);
    800 }
    801 
    802 template <class ELFT>
    803 typename ELFFile<ELFT>::Elf_Dyn_Iter
    804 ELFFile<ELFT>::end_dynamic_table(bool NULLEnd) const {
    805   if (!DynamicRegion.Addr)
    806     return Elf_Dyn_Iter(0, nullptr);
    807   Elf_Dyn_Iter Ret(DynamicRegion.EntSize,
    808                     (const char *)DynamicRegion.Addr + DynamicRegion.Size);
    809 
    810   if (NULLEnd) {
    811     Elf_Dyn_Iter Start = begin_dynamic_table();
    812     while (Start != Ret && Start->getTag() != ELF::DT_NULL)
    813       ++Start;
    814 
    815     // Include the DT_NULL.
    816     if (Start != Ret)
    817       ++Start;
    818     Ret = Start;
    819   }
    820   return Ret;
    821 }
    822 
    823 template <class ELFT>
    824 StringRef ELFFile<ELFT>::getLoadName() const {
    825   if (!dt_soname) {
    826     dt_soname = "";
    827     // Find the DT_SONAME entry
    828     for (const auto &Entry : dynamic_table())
    829       if (Entry.getTag() == ELF::DT_SONAME) {
    830         dt_soname = getDynamicString(Entry.getVal());
    831         break;
    832       }
    833   }
    834   return dt_soname;
    835 }
    836 
    837 template <class ELFT>
    838 template <typename T>
    839 const T *ELFFile<ELFT>::getEntry(uint32_t Section, uint32_t Entry) const {
    840   return getEntry<T>(getSection(Section), Entry);
    841 }
    842 
    843 template <class ELFT>
    844 template <typename T>
    845 const T *ELFFile<ELFT>::getEntry(const Elf_Shdr *Section,
    846                                  uint32_t Entry) const {
    847   return reinterpret_cast<const T *>(base() + Section->sh_offset +
    848                                      (Entry * Section->sh_entsize));
    849 }
    850 
    851 template <class ELFT>
    852 const typename ELFFile<ELFT>::Elf_Shdr *
    853 ELFFile<ELFT>::getSection(uint32_t index) const {
    854   if (index == 0)
    855     return nullptr;
    856   if (!SectionHeaderTable || index >= getNumSections())
    857     // FIXME: Proper error handling.
    858     report_fatal_error("Invalid section index!");
    859 
    860   return reinterpret_cast<const Elf_Shdr *>(
    861          reinterpret_cast<const char *>(SectionHeaderTable)
    862          + (index * Header->e_shentsize));
    863 }
    864 
    865 template <class ELFT>
    866 const char *ELFFile<ELFT>::getString(uint32_t section,
    867                                      ELF::Elf32_Word offset) const {
    868   return getString(getSection(section), offset);
    869 }
    870 
    871 template <class ELFT>
    872 const char *ELFFile<ELFT>::getString(const Elf_Shdr *section,
    873                                      ELF::Elf32_Word offset) const {
    874   assert(section && section->sh_type == ELF::SHT_STRTAB && "Invalid section!");
    875   if (offset >= section->sh_size)
    876     // FIXME: Proper error handling.
    877     report_fatal_error("Symbol name offset outside of string table!");
    878   return (const char *)base() + section->sh_offset + offset;
    879 }
    880 
    881 template <class ELFT>
    882 const char *ELFFile<ELFT>::getDynamicString(uintX_t Offset) const {
    883   if (!DynStrRegion.Addr || Offset >= DynStrRegion.Size)
    884     return nullptr;
    885   return (const char *)DynStrRegion.Addr + Offset;
    886 }
    887 
    888 template <class ELFT>
    889 ErrorOr<StringRef> ELFFile<ELFT>::getSymbolName(Elf_Sym_Iter Sym) const {
    890   if (!Sym.isDynamic())
    891     return getSymbolName(dot_symtab_sec, &*Sym);
    892 
    893   if (!DynStrRegion.Addr || Sym->st_name >= DynStrRegion.Size)
    894     return object_error::parse_failed;
    895   return StringRef(getDynamicString(Sym->st_name));
    896 }
    897 
    898 template <class ELFT>
    899 ErrorOr<StringRef> ELFFile<ELFT>::getSymbolName(const Elf_Shdr *Section,
    900                                                 const Elf_Sym *Symb) const {
    901   if (Symb->st_name == 0) {
    902     const Elf_Shdr *ContainingSec = getSection(Symb);
    903     if (ContainingSec)
    904       return getSectionName(ContainingSec);
    905   }
    906 
    907   const Elf_Shdr *StrTab = getSection(Section->sh_link);
    908   if (Symb->st_name >= StrTab->sh_size)
    909     return object_error::parse_failed;
    910   return StringRef(getString(StrTab, Symb->st_name));
    911 }
    912 
    913 template <class ELFT>
    914 ErrorOr<StringRef>
    915 ELFFile<ELFT>::getSectionName(const Elf_Shdr *Section) const {
    916   if (Section->sh_name >= dot_shstrtab_sec->sh_size)
    917     return object_error::parse_failed;
    918   return StringRef(getString(dot_shstrtab_sec, Section->sh_name));
    919 }
    920 
    921 template <class ELFT>
    922 ErrorOr<StringRef> ELFFile<ELFT>::getSymbolVersion(const Elf_Shdr *section,
    923                                                    const Elf_Sym *symb,
    924                                                    bool &IsDefault) const {
    925   // Handle non-dynamic symbols.
    926   if (section != DynSymRegion.Addr && section != nullptr) {
    927     // Non-dynamic symbols can have versions in their names
    928     // A name of the form 'foo@V1' indicates version 'V1', non-default.
    929     // A name of the form 'foo@@V2' indicates version 'V2', default version.
    930     ErrorOr<StringRef> SymName = getSymbolName(section, symb);
    931     if (!SymName)
    932       return SymName;
    933     StringRef Name = *SymName;
    934     size_t atpos = Name.find('@');
    935     if (atpos == StringRef::npos) {
    936       IsDefault = false;
    937       return StringRef("");
    938     }
    939     ++atpos;
    940     if (atpos < Name.size() && Name[atpos] == '@') {
    941       IsDefault = true;
    942       ++atpos;
    943     } else {
    944       IsDefault = false;
    945     }
    946     return Name.substr(atpos);
    947   }
    948 
    949   // This is a dynamic symbol. Look in the GNU symbol version table.
    950   if (!dot_gnu_version_sec) {
    951     // No version table.
    952     IsDefault = false;
    953     return StringRef("");
    954   }
    955 
    956   // Determine the position in the symbol table of this entry.
    957   size_t entry_index = ((const char *)symb - (const char *)DynSymRegion.Addr) /
    958                        DynSymRegion.EntSize;
    959 
    960   // Get the corresponding version index entry
    961   const Elf_Versym *vs = getEntry<Elf_Versym>(dot_gnu_version_sec, entry_index);
    962   size_t version_index = vs->vs_index & ELF::VERSYM_VERSION;
    963 
    964   // Special markers for unversioned symbols.
    965   if (version_index == ELF::VER_NDX_LOCAL ||
    966       version_index == ELF::VER_NDX_GLOBAL) {
    967     IsDefault = false;
    968     return StringRef("");
    969   }
    970 
    971   // Lookup this symbol in the version table
    972   LoadVersionMap();
    973   if (version_index >= VersionMap.size() || VersionMap[version_index].isNull())
    974     return object_error::parse_failed;
    975   const VersionMapEntry &entry = VersionMap[version_index];
    976 
    977   // Get the version name string
    978   size_t name_offset;
    979   if (entry.isVerdef()) {
    980     // The first Verdaux entry holds the name.
    981     name_offset = entry.getVerdef()->getAux()->vda_name;
    982   } else {
    983     name_offset = entry.getVernaux()->vna_name;
    984   }
    985 
    986   // Set IsDefault
    987   if (entry.isVerdef()) {
    988     IsDefault = !(vs->vs_index & ELF::VERSYM_HIDDEN);
    989   } else {
    990     IsDefault = false;
    991   }
    992 
    993   if (name_offset >= DynStrRegion.Size)
    994     return object_error::parse_failed;
    995   return StringRef(getDynamicString(name_offset));
    996 }
    997 
    998 /// This function returns the hash value for a symbol in the .dynsym section
    999 /// Name of the API remains consistent as specified in the libelf
   1000 /// REF : http://www.sco.com/developers/gabi/latest/ch5.dynamic.html#hash
   1001 static inline unsigned elf_hash(StringRef &symbolName) {
   1002   unsigned h = 0, g;
   1003   for (unsigned i = 0, j = symbolName.size(); i < j; i++) {
   1004     h = (h << 4) + symbolName[i];
   1005     g = h & 0xf0000000L;
   1006     if (g != 0)
   1007       h ^= g >> 24;
   1008     h &= ~g;
   1009   }
   1010   return h;
   1011 }
   1012 } // end namespace object
   1013 } // end namespace llvm
   1014 
   1015 #endif
   1016