Home | History | Annotate | Download | only in Object
      1 //===- ELFObjectFile.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 ELFObjectFile template class.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #ifndef LLVM_OBJECT_ELFOBJECTFILE_H
     15 #define LLVM_OBJECT_ELFOBJECTFILE_H
     16 
     17 #include "llvm/ADT/DenseMap.h"
     18 #include "llvm/ADT/PointerIntPair.h"
     19 #include "llvm/ADT/SmallVector.h"
     20 #include "llvm/ADT/StringSwitch.h"
     21 #include "llvm/ADT/Triple.h"
     22 #include "llvm/Object/ELF.h"
     23 #include "llvm/Object/ObjectFile.h"
     24 #include "llvm/Support/Casting.h"
     25 #include "llvm/Support/ELF.h"
     26 #include "llvm/Support/Endian.h"
     27 #include "llvm/Support/ErrorHandling.h"
     28 #include "llvm/Support/MemoryBuffer.h"
     29 #include "llvm/Support/raw_ostream.h"
     30 #include <algorithm>
     31 #include <cctype>
     32 #include <limits>
     33 #include <utility>
     34 
     35 namespace llvm {
     36 namespace object {
     37 
     38 class elf_symbol_iterator;
     39 class ELFSymbolRef;
     40 class ELFRelocationRef;
     41 
     42 class ELFObjectFileBase : public ObjectFile {
     43   friend class ELFSymbolRef;
     44   friend class ELFSectionRef;
     45   friend class ELFRelocationRef;
     46 
     47 protected:
     48   ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source);
     49 
     50   virtual uint64_t getSymbolSize(DataRefImpl Symb) const = 0;
     51   virtual uint8_t getSymbolOther(DataRefImpl Symb) const = 0;
     52   virtual uint8_t getSymbolELFType(DataRefImpl Symb) const = 0;
     53 
     54   virtual uint32_t getSectionType(DataRefImpl Sec) const = 0;
     55   virtual uint64_t getSectionFlags(DataRefImpl Sec) const = 0;
     56 
     57   virtual ErrorOr<int64_t> getRelocationAddend(DataRefImpl Rel) const = 0;
     58 public:
     59 
     60   typedef iterator_range<elf_symbol_iterator> elf_symbol_iterator_range;
     61   virtual elf_symbol_iterator_range getDynamicSymbolIterators() const = 0;
     62 
     63   elf_symbol_iterator_range symbols() const;
     64 
     65   static inline bool classof(const Binary *v) { return v->isELF(); }
     66 };
     67 
     68 class ELFSectionRef : public SectionRef {
     69 public:
     70   ELFSectionRef(const SectionRef &B) : SectionRef(B) {
     71     assert(isa<ELFObjectFileBase>(SectionRef::getObject()));
     72   }
     73 
     74   const ELFObjectFileBase *getObject() const {
     75     return cast<ELFObjectFileBase>(SectionRef::getObject());
     76   }
     77 
     78   uint32_t getType() const {
     79     return getObject()->getSectionType(getRawDataRefImpl());
     80   }
     81 
     82   uint64_t getFlags() const {
     83     return getObject()->getSectionFlags(getRawDataRefImpl());
     84   }
     85 };
     86 
     87 class elf_section_iterator : public section_iterator {
     88 public:
     89   elf_section_iterator(const section_iterator &B) : section_iterator(B) {
     90     assert(isa<ELFObjectFileBase>(B->getObject()));
     91   }
     92 
     93   const ELFSectionRef *operator->() const {
     94     return static_cast<const ELFSectionRef *>(section_iterator::operator->());
     95   }
     96 
     97   const ELFSectionRef &operator*() const {
     98     return static_cast<const ELFSectionRef &>(section_iterator::operator*());
     99   }
    100 };
    101 
    102 class ELFSymbolRef : public SymbolRef {
    103 public:
    104   ELFSymbolRef(const SymbolRef &B) : SymbolRef(B) {
    105     assert(isa<ELFObjectFileBase>(SymbolRef::getObject()));
    106   }
    107 
    108   const ELFObjectFileBase *getObject() const {
    109     return cast<ELFObjectFileBase>(BasicSymbolRef::getObject());
    110   }
    111 
    112   uint64_t getSize() const {
    113     return getObject()->getSymbolSize(getRawDataRefImpl());
    114   }
    115 
    116   uint8_t getOther() const {
    117     return getObject()->getSymbolOther(getRawDataRefImpl());
    118   }
    119 
    120   uint8_t getELFType() const {
    121     return getObject()->getSymbolELFType(getRawDataRefImpl());
    122   }
    123 };
    124 
    125 class elf_symbol_iterator : public symbol_iterator {
    126 public:
    127   elf_symbol_iterator(const basic_symbol_iterator &B)
    128       : symbol_iterator(SymbolRef(B->getRawDataRefImpl(),
    129                                   cast<ELFObjectFileBase>(B->getObject()))) {}
    130 
    131   const ELFSymbolRef *operator->() const {
    132     return static_cast<const ELFSymbolRef *>(symbol_iterator::operator->());
    133   }
    134 
    135   const ELFSymbolRef &operator*() const {
    136     return static_cast<const ELFSymbolRef &>(symbol_iterator::operator*());
    137   }
    138 };
    139 
    140 class ELFRelocationRef : public RelocationRef {
    141 public:
    142   ELFRelocationRef(const RelocationRef &B) : RelocationRef(B) {
    143     assert(isa<ELFObjectFileBase>(RelocationRef::getObject()));
    144   }
    145 
    146   const ELFObjectFileBase *getObject() const {
    147     return cast<ELFObjectFileBase>(RelocationRef::getObject());
    148   }
    149 
    150   ErrorOr<int64_t> getAddend() const {
    151     return getObject()->getRelocationAddend(getRawDataRefImpl());
    152   }
    153 };
    154 
    155 class elf_relocation_iterator : public relocation_iterator {
    156 public:
    157   elf_relocation_iterator(const relocation_iterator &B)
    158       : relocation_iterator(RelocationRef(
    159             B->getRawDataRefImpl(), cast<ELFObjectFileBase>(B->getObject()))) {}
    160 
    161   const ELFRelocationRef *operator->() const {
    162     return static_cast<const ELFRelocationRef *>(
    163         relocation_iterator::operator->());
    164   }
    165 
    166   const ELFRelocationRef &operator*() const {
    167     return static_cast<const ELFRelocationRef &>(
    168         relocation_iterator::operator*());
    169   }
    170 };
    171 
    172 inline ELFObjectFileBase::elf_symbol_iterator_range
    173 ELFObjectFileBase::symbols() const {
    174   return elf_symbol_iterator_range(symbol_begin(), symbol_end());
    175 }
    176 
    177 template <class ELFT> class ELFObjectFile : public ELFObjectFileBase {
    178   uint64_t getSymbolSize(DataRefImpl Sym) const override;
    179 
    180 public:
    181   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
    182 
    183   typedef typename ELFFile<ELFT>::uintX_t uintX_t;
    184 
    185   typedef typename ELFFile<ELFT>::Elf_Sym Elf_Sym;
    186   typedef typename ELFFile<ELFT>::Elf_Shdr Elf_Shdr;
    187   typedef typename ELFFile<ELFT>::Elf_Ehdr Elf_Ehdr;
    188   typedef typename ELFFile<ELFT>::Elf_Rel Elf_Rel;
    189   typedef typename ELFFile<ELFT>::Elf_Rela Elf_Rela;
    190   typedef typename ELFFile<ELFT>::Elf_Dyn Elf_Dyn;
    191 
    192 protected:
    193   ELFFile<ELFT> EF;
    194 
    195   const Elf_Shdr *DotDynSymSec = nullptr; // Dynamic symbol table section.
    196   const Elf_Shdr *DotSymtabSec = nullptr; // Symbol table section.
    197   ArrayRef<Elf_Word> ShndxTable;
    198 
    199   void moveSymbolNext(DataRefImpl &Symb) const override;
    200   ErrorOr<StringRef> getSymbolName(DataRefImpl Symb) const override;
    201   ErrorOr<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
    202   uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
    203   uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
    204   uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
    205   uint32_t getSymbolFlags(DataRefImpl Symb) const override;
    206   uint8_t getSymbolOther(DataRefImpl Symb) const override;
    207   uint8_t getSymbolELFType(DataRefImpl Symb) const override;
    208   SymbolRef::Type getSymbolType(DataRefImpl Symb) const override;
    209   ErrorOr<section_iterator> getSymbolSection(const Elf_Sym *Symb,
    210                                              const Elf_Shdr *SymTab) const;
    211   ErrorOr<section_iterator> getSymbolSection(DataRefImpl Symb) const override;
    212 
    213   void moveSectionNext(DataRefImpl &Sec) const override;
    214   std::error_code getSectionName(DataRefImpl Sec,
    215                                  StringRef &Res) const override;
    216   uint64_t getSectionAddress(DataRefImpl Sec) const override;
    217   uint64_t getSectionSize(DataRefImpl Sec) const override;
    218   std::error_code getSectionContents(DataRefImpl Sec,
    219                                      StringRef &Res) const override;
    220   uint64_t getSectionAlignment(DataRefImpl Sec) const override;
    221   bool isSectionText(DataRefImpl Sec) const override;
    222   bool isSectionData(DataRefImpl Sec) const override;
    223   bool isSectionBSS(DataRefImpl Sec) const override;
    224   bool isSectionVirtual(DataRefImpl Sec) const override;
    225   relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
    226   relocation_iterator section_rel_end(DataRefImpl Sec) const override;
    227   section_iterator getRelocatedSection(DataRefImpl Sec) const override;
    228 
    229   void moveRelocationNext(DataRefImpl &Rel) const override;
    230   uint64_t getRelocationOffset(DataRefImpl Rel) const override;
    231   symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
    232   uint64_t getRelocationType(DataRefImpl Rel) const override;
    233   void getRelocationTypeName(DataRefImpl Rel,
    234                              SmallVectorImpl<char> &Result) const override;
    235 
    236   uint32_t getSectionType(DataRefImpl Sec) const override;
    237   uint64_t getSectionFlags(DataRefImpl Sec) const override;
    238   StringRef getRelocationTypeName(uint32_t Type) const;
    239 
    240   /// \brief Get the relocation section that contains \a Rel.
    241   const Elf_Shdr *getRelSection(DataRefImpl Rel) const {
    242     return *EF.getSection(Rel.d.a);
    243   }
    244 
    245   DataRefImpl toDRI(const Elf_Shdr *SymTable, unsigned SymbolNum) const {
    246     DataRefImpl DRI;
    247     if (!SymTable) {
    248       DRI.d.a = 0;
    249       DRI.d.b = 0;
    250       return DRI;
    251     }
    252     assert(SymTable->sh_type == ELF::SHT_SYMTAB ||
    253            SymTable->sh_type == ELF::SHT_DYNSYM);
    254 
    255     uintptr_t SHT = reinterpret_cast<uintptr_t>(EF.section_begin());
    256     unsigned SymTableIndex =
    257         (reinterpret_cast<uintptr_t>(SymTable) - SHT) / sizeof(Elf_Shdr);
    258 
    259     DRI.d.a = SymTableIndex;
    260     DRI.d.b = SymbolNum;
    261     return DRI;
    262   }
    263 
    264   const Elf_Shdr *toELFShdrIter(DataRefImpl Sec) const {
    265     return reinterpret_cast<const Elf_Shdr *>(Sec.p);
    266   }
    267 
    268   DataRefImpl toDRI(const Elf_Shdr *Sec) const {
    269     DataRefImpl DRI;
    270     DRI.p = reinterpret_cast<uintptr_t>(Sec);
    271     return DRI;
    272   }
    273 
    274   DataRefImpl toDRI(const Elf_Dyn *Dyn) const {
    275     DataRefImpl DRI;
    276     DRI.p = reinterpret_cast<uintptr_t>(Dyn);
    277     return DRI;
    278   }
    279 
    280   bool isExportedToOtherDSO(const Elf_Sym *ESym) const {
    281     unsigned char Binding = ESym->getBinding();
    282     unsigned char Visibility = ESym->getVisibility();
    283 
    284     // A symbol is exported if its binding is either GLOBAL or WEAK, and its
    285     // visibility is either DEFAULT or PROTECTED. All other symbols are not
    286     // exported.
    287     if ((Binding == ELF::STB_GLOBAL || Binding == ELF::STB_WEAK) &&
    288         (Visibility == ELF::STV_DEFAULT || Visibility == ELF::STV_PROTECTED))
    289       return true;
    290 
    291     return false;
    292   }
    293 
    294   // This flag is used for classof, to distinguish ELFObjectFile from
    295   // its subclass. If more subclasses will be created, this flag will
    296   // have to become an enum.
    297   bool isDyldELFObject;
    298 
    299 public:
    300   ELFObjectFile(MemoryBufferRef Object, std::error_code &EC);
    301 
    302   const Elf_Rel *getRel(DataRefImpl Rel) const;
    303   const Elf_Rela *getRela(DataRefImpl Rela) const;
    304 
    305   const Elf_Sym *getSymbol(DataRefImpl Sym) const {
    306     return EF.template getEntry<Elf_Sym>(Sym.d.a, Sym.d.b);
    307   }
    308 
    309   const Elf_Shdr *getSection(DataRefImpl Sec) const {
    310     return reinterpret_cast<const Elf_Shdr *>(Sec.p);
    311   }
    312 
    313   basic_symbol_iterator symbol_begin_impl() const override;
    314   basic_symbol_iterator symbol_end_impl() const override;
    315 
    316   elf_symbol_iterator dynamic_symbol_begin() const;
    317   elf_symbol_iterator dynamic_symbol_end() const;
    318 
    319   section_iterator section_begin() const override;
    320   section_iterator section_end() const override;
    321 
    322   ErrorOr<int64_t> getRelocationAddend(DataRefImpl Rel) const override;
    323 
    324   uint8_t getBytesInAddress() const override;
    325   StringRef getFileFormatName() const override;
    326   unsigned getArch() const override;
    327 
    328   std::error_code getPlatformFlags(unsigned &Result) const override {
    329     Result = EF.getHeader()->e_flags;
    330     return std::error_code();
    331   }
    332 
    333   const ELFFile<ELFT> *getELFFile() const { return &EF; }
    334 
    335   bool isDyldType() const { return isDyldELFObject; }
    336   static inline bool classof(const Binary *v) {
    337     return v->getType() == getELFType(ELFT::TargetEndianness == support::little,
    338                                       ELFT::Is64Bits);
    339   }
    340 
    341   elf_symbol_iterator_range getDynamicSymbolIterators() const override;
    342 
    343   bool isRelocatableObject() const override;
    344 };
    345 
    346 typedef ELFObjectFile<ELFType<support::little, false>> ELF32LEObjectFile;
    347 typedef ELFObjectFile<ELFType<support::little, true>> ELF64LEObjectFile;
    348 typedef ELFObjectFile<ELFType<support::big, false>> ELF32BEObjectFile;
    349 typedef ELFObjectFile<ELFType<support::big, true>> ELF64BEObjectFile;
    350 
    351 template <class ELFT>
    352 void ELFObjectFile<ELFT>::moveSymbolNext(DataRefImpl &Sym) const {
    353   ++Sym.d.b;
    354 }
    355 
    356 template <class ELFT>
    357 ErrorOr<StringRef> ELFObjectFile<ELFT>::getSymbolName(DataRefImpl Sym) const {
    358   const Elf_Sym *ESym = getSymbol(Sym);
    359   const Elf_Shdr *SymTableSec = *EF.getSection(Sym.d.a);
    360   const Elf_Shdr *StringTableSec = *EF.getSection(SymTableSec->sh_link);
    361   StringRef SymTable = *EF.getStringTable(StringTableSec);
    362   return ESym->getName(SymTable);
    363 }
    364 
    365 template <class ELFT>
    366 uint64_t ELFObjectFile<ELFT>::getSectionFlags(DataRefImpl Sec) const {
    367   return getSection(Sec)->sh_flags;
    368 }
    369 
    370 template <class ELFT>
    371 uint32_t ELFObjectFile<ELFT>::getSectionType(DataRefImpl Sec) const {
    372   return getSection(Sec)->sh_type;
    373 }
    374 
    375 template <class ELFT>
    376 uint64_t ELFObjectFile<ELFT>::getSymbolValueImpl(DataRefImpl Symb) const {
    377   const Elf_Sym *ESym = getSymbol(Symb);
    378   uint64_t Ret = ESym->st_value;
    379   if (ESym->st_shndx == ELF::SHN_ABS)
    380     return Ret;
    381 
    382   const Elf_Ehdr *Header = EF.getHeader();
    383   // Clear the ARM/Thumb or microMIPS indicator flag.
    384   if ((Header->e_machine == ELF::EM_ARM || Header->e_machine == ELF::EM_MIPS) &&
    385       ESym->getType() == ELF::STT_FUNC)
    386     Ret &= ~1;
    387 
    388   return Ret;
    389 }
    390 
    391 template <class ELFT>
    392 ErrorOr<uint64_t>
    393 ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb) const {
    394   uint64_t Result = getSymbolValue(Symb);
    395   const Elf_Sym *ESym = getSymbol(Symb);
    396   switch (ESym->st_shndx) {
    397   case ELF::SHN_COMMON:
    398   case ELF::SHN_UNDEF:
    399   case ELF::SHN_ABS:
    400     return Result;
    401   }
    402 
    403   const Elf_Ehdr *Header = EF.getHeader();
    404   const Elf_Shdr *SymTab = *EF.getSection(Symb.d.a);
    405 
    406   if (Header->e_type == ELF::ET_REL) {
    407     ErrorOr<const Elf_Shdr *> SectionOrErr =
    408         EF.getSection(ESym, SymTab, ShndxTable);
    409     if (std::error_code EC = SectionOrErr.getError())
    410       return EC;
    411     const Elf_Shdr *Section = *SectionOrErr;
    412     if (Section)
    413       Result += Section->sh_addr;
    414   }
    415 
    416   return Result;
    417 }
    418 
    419 template <class ELFT>
    420 uint32_t ELFObjectFile<ELFT>::getSymbolAlignment(DataRefImpl Symb) const {
    421   const Elf_Sym *Sym = getSymbol(Symb);
    422   if (Sym->st_shndx == ELF::SHN_COMMON)
    423     return Sym->st_value;
    424   return 0;
    425 }
    426 
    427 template <class ELFT>
    428 uint64_t ELFObjectFile<ELFT>::getSymbolSize(DataRefImpl Sym) const {
    429   return getSymbol(Sym)->st_size;
    430 }
    431 
    432 template <class ELFT>
    433 uint64_t ELFObjectFile<ELFT>::getCommonSymbolSizeImpl(DataRefImpl Symb) const {
    434   return getSymbol(Symb)->st_size;
    435 }
    436 
    437 template <class ELFT>
    438 uint8_t ELFObjectFile<ELFT>::getSymbolOther(DataRefImpl Symb) const {
    439   return getSymbol(Symb)->st_other;
    440 }
    441 
    442 template <class ELFT>
    443 uint8_t ELFObjectFile<ELFT>::getSymbolELFType(DataRefImpl Symb) const {
    444   return getSymbol(Symb)->getType();
    445 }
    446 
    447 template <class ELFT>
    448 SymbolRef::Type ELFObjectFile<ELFT>::getSymbolType(DataRefImpl Symb) const {
    449   const Elf_Sym *ESym = getSymbol(Symb);
    450 
    451   switch (ESym->getType()) {
    452   case ELF::STT_NOTYPE:
    453     return SymbolRef::ST_Unknown;
    454   case ELF::STT_SECTION:
    455     return SymbolRef::ST_Debug;
    456   case ELF::STT_FILE:
    457     return SymbolRef::ST_File;
    458   case ELF::STT_FUNC:
    459     return SymbolRef::ST_Function;
    460   case ELF::STT_OBJECT:
    461   case ELF::STT_COMMON:
    462   case ELF::STT_TLS:
    463     return SymbolRef::ST_Data;
    464   default:
    465     return SymbolRef::ST_Other;
    466   }
    467 }
    468 
    469 template <class ELFT>
    470 uint32_t ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Sym) const {
    471   const Elf_Sym *ESym = getSymbol(Sym);
    472 
    473   uint32_t Result = SymbolRef::SF_None;
    474 
    475   if (ESym->getBinding() != ELF::STB_LOCAL)
    476     Result |= SymbolRef::SF_Global;
    477 
    478   if (ESym->getBinding() == ELF::STB_WEAK)
    479     Result |= SymbolRef::SF_Weak;
    480 
    481   if (ESym->st_shndx == ELF::SHN_ABS)
    482     Result |= SymbolRef::SF_Absolute;
    483 
    484   if (ESym->getType() == ELF::STT_FILE || ESym->getType() == ELF::STT_SECTION ||
    485       ESym == EF.symbol_begin(DotSymtabSec) ||
    486       ESym == EF.symbol_begin(DotDynSymSec))
    487     Result |= SymbolRef::SF_FormatSpecific;
    488 
    489   if (EF.getHeader()->e_machine == ELF::EM_ARM) {
    490     if (ErrorOr<StringRef> NameOrErr = getSymbolName(Sym)) {
    491       StringRef Name = *NameOrErr;
    492       if (Name.startswith("$d") || Name.startswith("$t") ||
    493           Name.startswith("$a"))
    494         Result |= SymbolRef::SF_FormatSpecific;
    495     }
    496   }
    497 
    498   if (ESym->st_shndx == ELF::SHN_UNDEF)
    499     Result |= SymbolRef::SF_Undefined;
    500 
    501   if (ESym->getType() == ELF::STT_COMMON || ESym->st_shndx == ELF::SHN_COMMON)
    502     Result |= SymbolRef::SF_Common;
    503 
    504   if (isExportedToOtherDSO(ESym))
    505     Result |= SymbolRef::SF_Exported;
    506 
    507   if (ESym->getVisibility() == ELF::STV_HIDDEN)
    508     Result |= SymbolRef::SF_Hidden;
    509 
    510   return Result;
    511 }
    512 
    513 template <class ELFT>
    514 ErrorOr<section_iterator>
    515 ELFObjectFile<ELFT>::getSymbolSection(const Elf_Sym *ESym,
    516                                       const Elf_Shdr *SymTab) const {
    517   ErrorOr<const Elf_Shdr *> ESecOrErr = EF.getSection(ESym, SymTab, ShndxTable);
    518   if (std::error_code EC = ESecOrErr.getError())
    519     return EC;
    520 
    521   const Elf_Shdr *ESec = *ESecOrErr;
    522   if (!ESec)
    523     return section_end();
    524 
    525   DataRefImpl Sec;
    526   Sec.p = reinterpret_cast<intptr_t>(ESec);
    527   return section_iterator(SectionRef(Sec, this));
    528 }
    529 
    530 template <class ELFT>
    531 ErrorOr<section_iterator>
    532 ELFObjectFile<ELFT>::getSymbolSection(DataRefImpl Symb) const {
    533   const Elf_Sym *Sym = getSymbol(Symb);
    534   const Elf_Shdr *SymTab = *EF.getSection(Symb.d.a);
    535   return getSymbolSection(Sym, SymTab);
    536 }
    537 
    538 template <class ELFT>
    539 void ELFObjectFile<ELFT>::moveSectionNext(DataRefImpl &Sec) const {
    540   const Elf_Shdr *ESec = getSection(Sec);
    541   Sec = toDRI(++ESec);
    542 }
    543 
    544 template <class ELFT>
    545 std::error_code ELFObjectFile<ELFT>::getSectionName(DataRefImpl Sec,
    546                                                     StringRef &Result) const {
    547   ErrorOr<StringRef> Name = EF.getSectionName(&*getSection(Sec));
    548   if (!Name)
    549     return Name.getError();
    550   Result = *Name;
    551   return std::error_code();
    552 }
    553 
    554 template <class ELFT>
    555 uint64_t ELFObjectFile<ELFT>::getSectionAddress(DataRefImpl Sec) const {
    556   return getSection(Sec)->sh_addr;
    557 }
    558 
    559 template <class ELFT>
    560 uint64_t ELFObjectFile<ELFT>::getSectionSize(DataRefImpl Sec) const {
    561   return getSection(Sec)->sh_size;
    562 }
    563 
    564 template <class ELFT>
    565 std::error_code
    566 ELFObjectFile<ELFT>::getSectionContents(DataRefImpl Sec,
    567                                         StringRef &Result) const {
    568   const Elf_Shdr *EShdr = getSection(Sec);
    569   Result = StringRef((const char *)base() + EShdr->sh_offset, EShdr->sh_size);
    570   return std::error_code();
    571 }
    572 
    573 template <class ELFT>
    574 uint64_t ELFObjectFile<ELFT>::getSectionAlignment(DataRefImpl Sec) const {
    575   return getSection(Sec)->sh_addralign;
    576 }
    577 
    578 template <class ELFT>
    579 bool ELFObjectFile<ELFT>::isSectionText(DataRefImpl Sec) const {
    580   return getSection(Sec)->sh_flags & ELF::SHF_EXECINSTR;
    581 }
    582 
    583 template <class ELFT>
    584 bool ELFObjectFile<ELFT>::isSectionData(DataRefImpl Sec) const {
    585   const Elf_Shdr *EShdr = getSection(Sec);
    586   return EShdr->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) &&
    587          EShdr->sh_type == ELF::SHT_PROGBITS;
    588 }
    589 
    590 template <class ELFT>
    591 bool ELFObjectFile<ELFT>::isSectionBSS(DataRefImpl Sec) const {
    592   const Elf_Shdr *EShdr = getSection(Sec);
    593   return EShdr->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) &&
    594          EShdr->sh_type == ELF::SHT_NOBITS;
    595 }
    596 
    597 template <class ELFT>
    598 bool ELFObjectFile<ELFT>::isSectionVirtual(DataRefImpl Sec) const {
    599   return getSection(Sec)->sh_type == ELF::SHT_NOBITS;
    600 }
    601 
    602 template <class ELFT>
    603 relocation_iterator
    604 ELFObjectFile<ELFT>::section_rel_begin(DataRefImpl Sec) const {
    605   DataRefImpl RelData;
    606   uintptr_t SHT = reinterpret_cast<uintptr_t>(EF.section_begin());
    607   RelData.d.a = (Sec.p - SHT) / EF.getHeader()->e_shentsize;
    608   RelData.d.b = 0;
    609 
    610   const Elf_Shdr *S = reinterpret_cast<const Elf_Shdr *>(Sec.p);
    611   if (S->sh_type != ELF::SHT_RELA && S->sh_type != ELF::SHT_REL)
    612     return relocation_iterator(RelocationRef(RelData, this));
    613 
    614   const Elf_Shdr *RelSec = getRelSection(RelData);
    615   ErrorOr<const Elf_Shdr *> SymSecOrErr = EF.getSection(RelSec->sh_link);
    616   if (std::error_code EC = SymSecOrErr.getError())
    617     report_fatal_error(EC.message());
    618   const Elf_Shdr *SymSec = *SymSecOrErr;
    619   uint32_t SymSecType = SymSec->sh_type;
    620   if (SymSecType != ELF::SHT_SYMTAB && SymSecType != ELF::SHT_DYNSYM)
    621     report_fatal_error("Invalid symbol table section type!");
    622   if (SymSecType == ELF::SHT_DYNSYM)
    623     RelData.d.b = 1;
    624 
    625   return relocation_iterator(RelocationRef(RelData, this));
    626 }
    627 
    628 template <class ELFT>
    629 relocation_iterator
    630 ELFObjectFile<ELFT>::section_rel_end(DataRefImpl Sec) const {
    631   const Elf_Shdr *S = reinterpret_cast<const Elf_Shdr *>(Sec.p);
    632   relocation_iterator Begin = section_rel_begin(Sec);
    633   if (S->sh_type != ELF::SHT_RELA && S->sh_type != ELF::SHT_REL)
    634     return Begin;
    635   DataRefImpl RelData = Begin->getRawDataRefImpl();
    636   RelData.d.b += (S->sh_size / S->sh_entsize) << 1;
    637   return relocation_iterator(RelocationRef(RelData, this));
    638 }
    639 
    640 template <class ELFT>
    641 section_iterator
    642 ELFObjectFile<ELFT>::getRelocatedSection(DataRefImpl Sec) const {
    643   if (EF.getHeader()->e_type != ELF::ET_REL)
    644     return section_end();
    645 
    646   const Elf_Shdr *EShdr = getSection(Sec);
    647   uintX_t Type = EShdr->sh_type;
    648   if (Type != ELF::SHT_REL && Type != ELF::SHT_RELA)
    649     return section_end();
    650 
    651   ErrorOr<const Elf_Shdr *> R = EF.getSection(EShdr->sh_info);
    652   if (std::error_code EC = R.getError())
    653     report_fatal_error(EC.message());
    654   return section_iterator(SectionRef(toDRI(*R), this));
    655 }
    656 
    657 // Relocations
    658 template <class ELFT>
    659 void ELFObjectFile<ELFT>::moveRelocationNext(DataRefImpl &Rel) const {
    660   Rel.d.b += 2;
    661 }
    662 
    663 template <class ELFT>
    664 symbol_iterator
    665 ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel) const {
    666   uint32_t symbolIdx;
    667   const Elf_Shdr *sec = getRelSection(Rel);
    668   if (sec->sh_type == ELF::SHT_REL)
    669     symbolIdx = getRel(Rel)->getSymbol(EF.isMips64EL());
    670   else
    671     symbolIdx = getRela(Rel)->getSymbol(EF.isMips64EL());
    672   if (!symbolIdx)
    673     return symbol_end();
    674 
    675   bool IsDyn = Rel.d.b & 1;
    676   DataRefImpl SymbolData;
    677   if (IsDyn)
    678     SymbolData = toDRI(DotDynSymSec, symbolIdx);
    679   else
    680     SymbolData = toDRI(DotSymtabSec, symbolIdx);
    681   return symbol_iterator(SymbolRef(SymbolData, this));
    682 }
    683 
    684 template <class ELFT>
    685 uint64_t ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel) const {
    686   assert(EF.getHeader()->e_type == ELF::ET_REL &&
    687          "Only relocatable object files have relocation offsets");
    688   const Elf_Shdr *sec = getRelSection(Rel);
    689   if (sec->sh_type == ELF::SHT_REL)
    690     return getRel(Rel)->r_offset;
    691 
    692   return getRela(Rel)->r_offset;
    693 }
    694 
    695 template <class ELFT>
    696 uint64_t ELFObjectFile<ELFT>::getRelocationType(DataRefImpl Rel) const {
    697   const Elf_Shdr *sec = getRelSection(Rel);
    698   if (sec->sh_type == ELF::SHT_REL)
    699     return getRel(Rel)->getType(EF.isMips64EL());
    700   else
    701     return getRela(Rel)->getType(EF.isMips64EL());
    702 }
    703 
    704 template <class ELFT>
    705 StringRef ELFObjectFile<ELFT>::getRelocationTypeName(uint32_t Type) const {
    706   return getELFRelocationTypeName(EF.getHeader()->e_machine, Type);
    707 }
    708 
    709 template <class ELFT>
    710 void ELFObjectFile<ELFT>::getRelocationTypeName(
    711     DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
    712   uint32_t type = getRelocationType(Rel);
    713   EF.getRelocationTypeName(type, Result);
    714 }
    715 
    716 template <class ELFT>
    717 ErrorOr<int64_t>
    718 ELFObjectFile<ELFT>::getRelocationAddend(DataRefImpl Rel) const {
    719   if (getRelSection(Rel)->sh_type != ELF::SHT_RELA)
    720     return object_error::parse_failed;
    721   return (int64_t)getRela(Rel)->r_addend;
    722 }
    723 
    724 template <class ELFT>
    725 const typename ELFObjectFile<ELFT>::Elf_Rel *
    726 ELFObjectFile<ELFT>::getRel(DataRefImpl Rel) const {
    727   assert(getRelSection(Rel)->sh_type == ELF::SHT_REL);
    728   return EF.template getEntry<Elf_Rel>(Rel.d.a, Rel.d.b >> 1);
    729 }
    730 
    731 template <class ELFT>
    732 const typename ELFObjectFile<ELFT>::Elf_Rela *
    733 ELFObjectFile<ELFT>::getRela(DataRefImpl Rela) const {
    734   assert(getRelSection(Rela)->sh_type == ELF::SHT_RELA);
    735   return EF.template getEntry<Elf_Rela>(Rela.d.a, Rela.d.b >> 1);
    736 }
    737 
    738 template <class ELFT>
    739 ELFObjectFile<ELFT>::ELFObjectFile(MemoryBufferRef Object, std::error_code &EC)
    740     : ELFObjectFileBase(
    741           getELFType(ELFT::TargetEndianness == support::little, ELFT::Is64Bits),
    742           Object),
    743       EF(Data.getBuffer(), EC) {
    744   if (EC)
    745     return;
    746   for (const Elf_Shdr &Sec : EF.sections()) {
    747     switch (Sec.sh_type) {
    748     case ELF::SHT_DYNSYM: {
    749       if (DotDynSymSec) {
    750         // More than one .dynsym!
    751         EC = object_error::parse_failed;
    752         return;
    753       }
    754       DotDynSymSec = &Sec;
    755       break;
    756     }
    757     case ELF::SHT_SYMTAB: {
    758       if (DotSymtabSec) {
    759         // More than one .dynsym!
    760         EC = object_error::parse_failed;
    761         return;
    762       }
    763       DotSymtabSec = &Sec;
    764       break;
    765     }
    766     case ELF::SHT_SYMTAB_SHNDX: {
    767       ErrorOr<ArrayRef<Elf_Word>> TableOrErr = EF.getSHNDXTable(Sec);
    768       if ((EC = TableOrErr.getError()))
    769         return;
    770       ShndxTable = *TableOrErr;
    771       break;
    772     }
    773     }
    774   }
    775 }
    776 
    777 template <class ELFT>
    778 basic_symbol_iterator ELFObjectFile<ELFT>::symbol_begin_impl() const {
    779   DataRefImpl Sym = toDRI(DotSymtabSec, 0);
    780   return basic_symbol_iterator(SymbolRef(Sym, this));
    781 }
    782 
    783 template <class ELFT>
    784 basic_symbol_iterator ELFObjectFile<ELFT>::symbol_end_impl() const {
    785   const Elf_Shdr *SymTab = DotSymtabSec;
    786   if (!SymTab)
    787     return symbol_begin_impl();
    788   DataRefImpl Sym = toDRI(SymTab, SymTab->sh_size / sizeof(Elf_Sym));
    789   return basic_symbol_iterator(SymbolRef(Sym, this));
    790 }
    791 
    792 template <class ELFT>
    793 elf_symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_begin() const {
    794   DataRefImpl Sym = toDRI(DotDynSymSec, 0);
    795   return symbol_iterator(SymbolRef(Sym, this));
    796 }
    797 
    798 template <class ELFT>
    799 elf_symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_end() const {
    800   const Elf_Shdr *SymTab = DotDynSymSec;
    801   DataRefImpl Sym = toDRI(SymTab, SymTab->sh_size / sizeof(Elf_Sym));
    802   return basic_symbol_iterator(SymbolRef(Sym, this));
    803 }
    804 
    805 template <class ELFT>
    806 section_iterator ELFObjectFile<ELFT>::section_begin() const {
    807   return section_iterator(SectionRef(toDRI(EF.section_begin()), this));
    808 }
    809 
    810 template <class ELFT>
    811 section_iterator ELFObjectFile<ELFT>::section_end() const {
    812   return section_iterator(SectionRef(toDRI(EF.section_end()), this));
    813 }
    814 
    815 template <class ELFT>
    816 uint8_t ELFObjectFile<ELFT>::getBytesInAddress() const {
    817   return ELFT::Is64Bits ? 8 : 4;
    818 }
    819 
    820 template <class ELFT>
    821 StringRef ELFObjectFile<ELFT>::getFileFormatName() const {
    822   bool IsLittleEndian = ELFT::TargetEndianness == support::little;
    823   switch (EF.getHeader()->e_ident[ELF::EI_CLASS]) {
    824   case ELF::ELFCLASS32:
    825     switch (EF.getHeader()->e_machine) {
    826     case ELF::EM_386:
    827       return "ELF32-i386";
    828     case ELF::EM_IAMCU:
    829       return "ELF32-iamcu";
    830     case ELF::EM_X86_64:
    831       return "ELF32-x86-64";
    832     case ELF::EM_ARM:
    833       return (IsLittleEndian ? "ELF32-arm-little" : "ELF32-arm-big");
    834     case ELF::EM_AVR:
    835       return "ELF32-avr";
    836     case ELF::EM_HEXAGON:
    837       return "ELF32-hexagon";
    838     case ELF::EM_MIPS:
    839       return "ELF32-mips";
    840     case ELF::EM_PPC:
    841       return "ELF32-ppc";
    842     case ELF::EM_SPARC:
    843     case ELF::EM_SPARC32PLUS:
    844       return "ELF32-sparc";
    845     default:
    846       return "ELF32-unknown";
    847     }
    848   case ELF::ELFCLASS64:
    849     switch (EF.getHeader()->e_machine) {
    850     case ELF::EM_386:
    851       return "ELF64-i386";
    852     case ELF::EM_X86_64:
    853       return "ELF64-x86-64";
    854     case ELF::EM_AARCH64:
    855       return (IsLittleEndian ? "ELF64-aarch64-little" : "ELF64-aarch64-big");
    856     case ELF::EM_PPC64:
    857       return "ELF64-ppc64";
    858     case ELF::EM_S390:
    859       return "ELF64-s390";
    860     case ELF::EM_SPARCV9:
    861       return "ELF64-sparc";
    862     case ELF::EM_MIPS:
    863       return "ELF64-mips";
    864     default:
    865       return "ELF64-unknown";
    866     }
    867   default:
    868     // FIXME: Proper error handling.
    869     report_fatal_error("Invalid ELFCLASS!");
    870   }
    871 }
    872 
    873 template <class ELFT>
    874 unsigned ELFObjectFile<ELFT>::getArch() const {
    875   bool IsLittleEndian = ELFT::TargetEndianness == support::little;
    876   switch (EF.getHeader()->e_machine) {
    877   case ELF::EM_386:
    878   case ELF::EM_IAMCU:
    879     return Triple::x86;
    880   case ELF::EM_X86_64:
    881     return Triple::x86_64;
    882   case ELF::EM_AARCH64:
    883     return Triple::aarch64;
    884   case ELF::EM_ARM:
    885     return Triple::arm;
    886   case ELF::EM_AVR:
    887     return Triple::avr;
    888   case ELF::EM_HEXAGON:
    889     return Triple::hexagon;
    890   case ELF::EM_MIPS:
    891     switch (EF.getHeader()->e_ident[ELF::EI_CLASS]) {
    892     case ELF::ELFCLASS32:
    893       return IsLittleEndian ? Triple::mipsel : Triple::mips;
    894     case ELF::ELFCLASS64:
    895       return IsLittleEndian ? Triple::mips64el : Triple::mips64;
    896     default:
    897       report_fatal_error("Invalid ELFCLASS!");
    898     }
    899   case ELF::EM_PPC:
    900     return Triple::ppc;
    901   case ELF::EM_PPC64:
    902     return IsLittleEndian ? Triple::ppc64le : Triple::ppc64;
    903   case ELF::EM_S390:
    904     return Triple::systemz;
    905 
    906   case ELF::EM_SPARC:
    907   case ELF::EM_SPARC32PLUS:
    908     return IsLittleEndian ? Triple::sparcel : Triple::sparc;
    909   case ELF::EM_SPARCV9:
    910     return Triple::sparcv9;
    911 
    912   default:
    913     return Triple::UnknownArch;
    914   }
    915 }
    916 
    917 template <class ELFT>
    918 ELFObjectFileBase::elf_symbol_iterator_range
    919 ELFObjectFile<ELFT>::getDynamicSymbolIterators() const {
    920   return make_range(dynamic_symbol_begin(), dynamic_symbol_end());
    921 }
    922 
    923 template <class ELFT> bool ELFObjectFile<ELFT>::isRelocatableObject() const {
    924   return EF.getHeader()->e_type == ELF::ET_REL;
    925 }
    926 
    927 }
    928 }
    929 
    930 #endif
    931