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