10b57cec5SDimitry Andric //===- ELFObjectFile.h - ELF object file implementation ---------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file declares the ELFObjectFile template class.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #ifndef LLVM_OBJECT_ELFOBJECTFILE_H
140b57cec5SDimitry Andric #define LLVM_OBJECT_ELFOBJECTFILE_H
150b57cec5SDimitry Andric 
160b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h"
170b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
180b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
190b57cec5SDimitry Andric #include "llvm/ADT/iterator_range.h"
200b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELF.h"
210b57cec5SDimitry Andric #include "llvm/Object/Binary.h"
220b57cec5SDimitry Andric #include "llvm/Object/ELF.h"
230b57cec5SDimitry Andric #include "llvm/Object/ELFTypes.h"
240b57cec5SDimitry Andric #include "llvm/Object/Error.h"
250b57cec5SDimitry Andric #include "llvm/Object/ObjectFile.h"
260b57cec5SDimitry Andric #include "llvm/Object/SymbolicFile.h"
270b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
2881ad6265SDimitry Andric #include "llvm/Support/ELFAttributeParser.h"
295ffd83dbSDimitry Andric #include "llvm/Support/ELFAttributes.h"
300b57cec5SDimitry Andric #include "llvm/Support/Error.h"
310b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
3281ad6265SDimitry Andric #include "llvm/Support/MemoryBufferRef.h"
3304eeddc0SDimitry Andric #include "llvm/Support/ScopedPrinter.h"
3406c3fb27SDimitry Andric #include "llvm/TargetParser/SubtargetFeature.h"
3506c3fb27SDimitry Andric #include "llvm/TargetParser/Triple.h"
360b57cec5SDimitry Andric #include <cassert>
370b57cec5SDimitry Andric #include <cstdint>
380b57cec5SDimitry Andric 
390b57cec5SDimitry Andric namespace llvm {
4081ad6265SDimitry Andric 
4181ad6265SDimitry Andric template <typename T> class SmallVectorImpl;
4281ad6265SDimitry Andric 
430b57cec5SDimitry Andric namespace object {
440b57cec5SDimitry Andric 
458bcb0991SDimitry Andric constexpr int NumElfSymbolTypes = 16;
460b57cec5SDimitry Andric extern const llvm::EnumEntry<unsigned> ElfSymbolTypes[NumElfSymbolTypes];
470b57cec5SDimitry Andric 
480b57cec5SDimitry Andric class elf_symbol_iterator;
490b57cec5SDimitry Andric 
5006c3fb27SDimitry Andric struct ELFPltEntry {
5106c3fb27SDimitry Andric   StringRef Section;
5206c3fb27SDimitry Andric   std::optional<DataRefImpl> Symbol;
5306c3fb27SDimitry Andric   uint64_t Address;
5406c3fb27SDimitry Andric };
5506c3fb27SDimitry Andric 
560b57cec5SDimitry Andric class ELFObjectFileBase : public ObjectFile {
570b57cec5SDimitry Andric   friend class ELFRelocationRef;
580b57cec5SDimitry Andric   friend class ELFSectionRef;
590b57cec5SDimitry Andric   friend class ELFSymbolRef;
600b57cec5SDimitry Andric 
61e8d8bef9SDimitry Andric   SubtargetFeatures getMIPSFeatures() const;
62e8d8bef9SDimitry Andric   SubtargetFeatures getARMFeatures() const;
63bdd1243dSDimitry Andric   Expected<SubtargetFeatures> getRISCVFeatures() const;
64bdd1243dSDimitry Andric   SubtargetFeatures getLoongArchFeatures() const;
65e8d8bef9SDimitry Andric 
66e8d8bef9SDimitry Andric   StringRef getAMDGPUCPUName() const;
67cb14a3feSDimitry Andric   StringRef getNVPTXCPUName() const;
68e8d8bef9SDimitry Andric 
690b57cec5SDimitry Andric protected:
700b57cec5SDimitry Andric   ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source);
710b57cec5SDimitry Andric 
720b57cec5SDimitry Andric   virtual uint64_t getSymbolSize(DataRefImpl Symb) const = 0;
730b57cec5SDimitry Andric   virtual uint8_t getSymbolBinding(DataRefImpl Symb) const = 0;
740b57cec5SDimitry Andric   virtual uint8_t getSymbolOther(DataRefImpl Symb) const = 0;
750b57cec5SDimitry Andric   virtual uint8_t getSymbolELFType(DataRefImpl Symb) const = 0;
760b57cec5SDimitry Andric 
770b57cec5SDimitry Andric   virtual uint32_t getSectionType(DataRefImpl Sec) const = 0;
780b57cec5SDimitry Andric   virtual uint64_t getSectionFlags(DataRefImpl Sec) const = 0;
790b57cec5SDimitry Andric   virtual uint64_t getSectionOffset(DataRefImpl Sec) const = 0;
800b57cec5SDimitry Andric 
810b57cec5SDimitry Andric   virtual Expected<int64_t> getRelocationAddend(DataRefImpl Rel) const = 0;
825ffd83dbSDimitry Andric   virtual Error getBuildAttributes(ELFAttributeParser &Attributes) const = 0;
830b57cec5SDimitry Andric 
840b57cec5SDimitry Andric public:
850b57cec5SDimitry Andric   using elf_symbol_iterator_range = iterator_range<elf_symbol_iterator>;
860b57cec5SDimitry Andric 
870b57cec5SDimitry Andric   virtual elf_symbol_iterator_range getDynamicSymbolIterators() const = 0;
880b57cec5SDimitry Andric 
890b57cec5SDimitry Andric   /// Returns platform-specific object flags, if any.
900b57cec5SDimitry Andric   virtual unsigned getPlatformFlags() const = 0;
910b57cec5SDimitry Andric 
920b57cec5SDimitry Andric   elf_symbol_iterator_range symbols() const;
930b57cec5SDimitry Andric 
classof(const Binary * v)940b57cec5SDimitry Andric   static bool classof(const Binary *v) { return v->isELF(); }
950b57cec5SDimitry Andric 
96bdd1243dSDimitry Andric   Expected<SubtargetFeatures> getFeatures() const override;
970b57cec5SDimitry Andric 
98bdd1243dSDimitry Andric   std::optional<StringRef> tryGetCPUName() const override;
990b57cec5SDimitry Andric 
1000b57cec5SDimitry Andric   void setARMSubArch(Triple &TheTriple) const override;
1010b57cec5SDimitry Andric 
1020b57cec5SDimitry Andric   virtual uint16_t getEType() const = 0;
1030b57cec5SDimitry Andric 
1040b57cec5SDimitry Andric   virtual uint16_t getEMachine() const = 0;
1050b57cec5SDimitry Andric 
10606c3fb27SDimitry Andric   std::vector<ELFPltEntry> getPltEntries() const;
107349cc55cSDimitry Andric 
108349cc55cSDimitry Andric   /// Returns a vector containing a symbol version for each dynamic symbol.
109349cc55cSDimitry Andric   /// Returns an empty vector if version sections do not exist.
110349cc55cSDimitry Andric   Expected<std::vector<VersionEntry>> readDynsymVersions() const;
11181ad6265SDimitry Andric 
11281ad6265SDimitry Andric   /// Returns a vector of all BB address maps in the object file. When
1137a6dacacSDimitry Andric   /// `TextSectionIndex` is specified, only returns the BB address maps
1147a6dacacSDimitry Andric   /// corresponding to the section with that index. When `PGOAnalyses`is
1157a6dacacSDimitry Andric   /// specified (PGOAnalyses is not nullptr), the vector is cleared then filled
1167a6dacacSDimitry Andric   /// with extra PGO data. `PGOAnalyses` will always be the same length as the
1177a6dacacSDimitry Andric   /// return value when it is requested assuming no error occurs. Upon failure,
1187a6dacacSDimitry Andric   /// `PGOAnalyses` will be emptied.
11981ad6265SDimitry Andric   Expected<std::vector<BBAddrMap>>
1205f757f3fSDimitry Andric   readBBAddrMap(std::optional<unsigned> TextSectionIndex = std::nullopt,
1215f757f3fSDimitry Andric                 std::vector<PGOAnalysisMap> *PGOAnalyses = nullptr) const;
1220b57cec5SDimitry Andric };
1230b57cec5SDimitry Andric 
1240b57cec5SDimitry Andric class ELFSectionRef : public SectionRef {
1250b57cec5SDimitry Andric public:
ELFSectionRef(const SectionRef & B)1260b57cec5SDimitry Andric   ELFSectionRef(const SectionRef &B) : SectionRef(B) {
1270b57cec5SDimitry Andric     assert(isa<ELFObjectFileBase>(SectionRef::getObject()));
1280b57cec5SDimitry Andric   }
1290b57cec5SDimitry Andric 
getObject()1300b57cec5SDimitry Andric   const ELFObjectFileBase *getObject() const {
1310b57cec5SDimitry Andric     return cast<ELFObjectFileBase>(SectionRef::getObject());
1320b57cec5SDimitry Andric   }
1330b57cec5SDimitry Andric 
getType()1340b57cec5SDimitry Andric   uint32_t getType() const {
1350b57cec5SDimitry Andric     return getObject()->getSectionType(getRawDataRefImpl());
1360b57cec5SDimitry Andric   }
1370b57cec5SDimitry Andric 
getFlags()1380b57cec5SDimitry Andric   uint64_t getFlags() const {
1390b57cec5SDimitry Andric     return getObject()->getSectionFlags(getRawDataRefImpl());
1400b57cec5SDimitry Andric   }
1410b57cec5SDimitry Andric 
getOffset()1420b57cec5SDimitry Andric   uint64_t getOffset() const {
1430b57cec5SDimitry Andric     return getObject()->getSectionOffset(getRawDataRefImpl());
1440b57cec5SDimitry Andric   }
1450b57cec5SDimitry Andric };
1460b57cec5SDimitry Andric 
1470b57cec5SDimitry Andric class elf_section_iterator : public section_iterator {
1480b57cec5SDimitry Andric public:
elf_section_iterator(const section_iterator & B)1490b57cec5SDimitry Andric   elf_section_iterator(const section_iterator &B) : section_iterator(B) {
1500b57cec5SDimitry Andric     assert(isa<ELFObjectFileBase>(B->getObject()));
1510b57cec5SDimitry Andric   }
1520b57cec5SDimitry Andric 
1530b57cec5SDimitry Andric   const ELFSectionRef *operator->() const {
1540b57cec5SDimitry Andric     return static_cast<const ELFSectionRef *>(section_iterator::operator->());
1550b57cec5SDimitry Andric   }
1560b57cec5SDimitry Andric 
1570b57cec5SDimitry Andric   const ELFSectionRef &operator*() const {
1580b57cec5SDimitry Andric     return static_cast<const ELFSectionRef &>(section_iterator::operator*());
1590b57cec5SDimitry Andric   }
1600b57cec5SDimitry Andric };
1610b57cec5SDimitry Andric 
1620b57cec5SDimitry Andric class ELFSymbolRef : public SymbolRef {
1630b57cec5SDimitry Andric public:
ELFSymbolRef(const SymbolRef & B)1640b57cec5SDimitry Andric   ELFSymbolRef(const SymbolRef &B) : SymbolRef(B) {
1650b57cec5SDimitry Andric     assert(isa<ELFObjectFileBase>(SymbolRef::getObject()));
1660b57cec5SDimitry Andric   }
1670b57cec5SDimitry Andric 
getObject()1680b57cec5SDimitry Andric   const ELFObjectFileBase *getObject() const {
1690b57cec5SDimitry Andric     return cast<ELFObjectFileBase>(BasicSymbolRef::getObject());
1700b57cec5SDimitry Andric   }
1710b57cec5SDimitry Andric 
getSize()1720b57cec5SDimitry Andric   uint64_t getSize() const {
1730b57cec5SDimitry Andric     return getObject()->getSymbolSize(getRawDataRefImpl());
1740b57cec5SDimitry Andric   }
1750b57cec5SDimitry Andric 
getBinding()1760b57cec5SDimitry Andric   uint8_t getBinding() const {
1770b57cec5SDimitry Andric     return getObject()->getSymbolBinding(getRawDataRefImpl());
1780b57cec5SDimitry Andric   }
1790b57cec5SDimitry Andric 
getOther()1800b57cec5SDimitry Andric   uint8_t getOther() const {
1810b57cec5SDimitry Andric     return getObject()->getSymbolOther(getRawDataRefImpl());
1820b57cec5SDimitry Andric   }
1830b57cec5SDimitry Andric 
getELFType()1840b57cec5SDimitry Andric   uint8_t getELFType() const {
1850b57cec5SDimitry Andric     return getObject()->getSymbolELFType(getRawDataRefImpl());
1860b57cec5SDimitry Andric   }
1870b57cec5SDimitry Andric 
getELFTypeName()1880b57cec5SDimitry Andric   StringRef getELFTypeName() const {
1890b57cec5SDimitry Andric     uint8_t Type = getELFType();
190bdd1243dSDimitry Andric     for (const auto &EE : ElfSymbolTypes) {
1910b57cec5SDimitry Andric       if (EE.Value == Type) {
1920b57cec5SDimitry Andric         return EE.AltName;
1930b57cec5SDimitry Andric       }
1940b57cec5SDimitry Andric     }
1950b57cec5SDimitry Andric     return "";
1960b57cec5SDimitry Andric   }
1970b57cec5SDimitry Andric };
1980b57cec5SDimitry Andric 
1990b57cec5SDimitry Andric class elf_symbol_iterator : public symbol_iterator {
2000b57cec5SDimitry Andric public:
elf_symbol_iterator(const basic_symbol_iterator & B)2010b57cec5SDimitry Andric   elf_symbol_iterator(const basic_symbol_iterator &B)
2020b57cec5SDimitry Andric       : symbol_iterator(SymbolRef(B->getRawDataRefImpl(),
2030b57cec5SDimitry Andric                                   cast<ELFObjectFileBase>(B->getObject()))) {}
2040b57cec5SDimitry Andric 
2050b57cec5SDimitry Andric   const ELFSymbolRef *operator->() const {
2060b57cec5SDimitry Andric     return static_cast<const ELFSymbolRef *>(symbol_iterator::operator->());
2070b57cec5SDimitry Andric   }
2080b57cec5SDimitry Andric 
2090b57cec5SDimitry Andric   const ELFSymbolRef &operator*() const {
2100b57cec5SDimitry Andric     return static_cast<const ELFSymbolRef &>(symbol_iterator::operator*());
2110b57cec5SDimitry Andric   }
2120b57cec5SDimitry Andric };
2130b57cec5SDimitry Andric 
2140b57cec5SDimitry Andric class ELFRelocationRef : public RelocationRef {
2150b57cec5SDimitry Andric public:
ELFRelocationRef(const RelocationRef & B)2160b57cec5SDimitry Andric   ELFRelocationRef(const RelocationRef &B) : RelocationRef(B) {
2170b57cec5SDimitry Andric     assert(isa<ELFObjectFileBase>(RelocationRef::getObject()));
2180b57cec5SDimitry Andric   }
2190b57cec5SDimitry Andric 
getObject()2200b57cec5SDimitry Andric   const ELFObjectFileBase *getObject() const {
2210b57cec5SDimitry Andric     return cast<ELFObjectFileBase>(RelocationRef::getObject());
2220b57cec5SDimitry Andric   }
2230b57cec5SDimitry Andric 
getAddend()2240b57cec5SDimitry Andric   Expected<int64_t> getAddend() const {
2250b57cec5SDimitry Andric     return getObject()->getRelocationAddend(getRawDataRefImpl());
2260b57cec5SDimitry Andric   }
2270b57cec5SDimitry Andric };
2280b57cec5SDimitry Andric 
2290b57cec5SDimitry Andric class elf_relocation_iterator : public relocation_iterator {
2300b57cec5SDimitry Andric public:
elf_relocation_iterator(const relocation_iterator & B)2310b57cec5SDimitry Andric   elf_relocation_iterator(const relocation_iterator &B)
2320b57cec5SDimitry Andric       : relocation_iterator(RelocationRef(
2330b57cec5SDimitry Andric             B->getRawDataRefImpl(), cast<ELFObjectFileBase>(B->getObject()))) {}
2340b57cec5SDimitry Andric 
2350b57cec5SDimitry Andric   const ELFRelocationRef *operator->() const {
2360b57cec5SDimitry Andric     return static_cast<const ELFRelocationRef *>(
2370b57cec5SDimitry Andric         relocation_iterator::operator->());
2380b57cec5SDimitry Andric   }
2390b57cec5SDimitry Andric 
2400b57cec5SDimitry Andric   const ELFRelocationRef &operator*() const {
2410b57cec5SDimitry Andric     return static_cast<const ELFRelocationRef &>(
2420b57cec5SDimitry Andric         relocation_iterator::operator*());
2430b57cec5SDimitry Andric   }
2440b57cec5SDimitry Andric };
2450b57cec5SDimitry Andric 
2460b57cec5SDimitry Andric inline ELFObjectFileBase::elf_symbol_iterator_range
symbols()2470b57cec5SDimitry Andric ELFObjectFileBase::symbols() const {
2480b57cec5SDimitry Andric   return elf_symbol_iterator_range(symbol_begin(), symbol_end());
2490b57cec5SDimitry Andric }
2500b57cec5SDimitry Andric 
2510b57cec5SDimitry Andric template <class ELFT> class ELFObjectFile : public ELFObjectFileBase {
2520b57cec5SDimitry Andric   uint16_t getEMachine() const override;
2530b57cec5SDimitry Andric   uint16_t getEType() const override;
2540b57cec5SDimitry Andric   uint64_t getSymbolSize(DataRefImpl Sym) const override;
2550b57cec5SDimitry Andric 
2560b57cec5SDimitry Andric public:
LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)2570b57cec5SDimitry Andric   LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
2580b57cec5SDimitry Andric 
2598bcb0991SDimitry Andric   SectionRef toSectionRef(const Elf_Shdr *Sec) const {
2608bcb0991SDimitry Andric     return SectionRef(toDRI(Sec), this);
2618bcb0991SDimitry Andric   }
2628bcb0991SDimitry Andric 
toSymbolRef(const Elf_Shdr * SymTable,unsigned SymbolNum)263e8d8bef9SDimitry Andric   ELFSymbolRef toSymbolRef(const Elf_Shdr *SymTable, unsigned SymbolNum) const {
264e8d8bef9SDimitry Andric     return ELFSymbolRef({toDRI(SymTable, SymbolNum), this});
265e8d8bef9SDimitry Andric   }
266e8d8bef9SDimitry Andric 
IsContentValid()267e8d8bef9SDimitry Andric   bool IsContentValid() const { return ContentValid; }
268e8d8bef9SDimitry Andric 
2690b57cec5SDimitry Andric private:
2700b57cec5SDimitry Andric   ELFObjectFile(MemoryBufferRef Object, ELFFile<ELFT> EF,
2710b57cec5SDimitry Andric                 const Elf_Shdr *DotDynSymSec, const Elf_Shdr *DotSymtabSec,
272e8d8bef9SDimitry Andric                 const Elf_Shdr *DotSymtabShndxSec);
273e8d8bef9SDimitry Andric 
274e8d8bef9SDimitry Andric   bool ContentValid = false;
2750b57cec5SDimitry Andric 
2760b57cec5SDimitry Andric protected:
2770b57cec5SDimitry Andric   ELFFile<ELFT> EF;
2780b57cec5SDimitry Andric 
2790b57cec5SDimitry Andric   const Elf_Shdr *DotDynSymSec = nullptr; // Dynamic symbol table section.
2800b57cec5SDimitry Andric   const Elf_Shdr *DotSymtabSec = nullptr; // Symbol table section.
281e8d8bef9SDimitry Andric   const Elf_Shdr *DotSymtabShndxSec = nullptr; // SHT_SYMTAB_SHNDX section.
282e8d8bef9SDimitry Andric 
283e8d8bef9SDimitry Andric   Error initContent() override;
2840b57cec5SDimitry Andric 
2850b57cec5SDimitry Andric   void moveSymbolNext(DataRefImpl &Symb) const override;
2860b57cec5SDimitry Andric   Expected<StringRef> getSymbolName(DataRefImpl Symb) const override;
2870b57cec5SDimitry Andric   Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
2880b57cec5SDimitry Andric   uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
2890b57cec5SDimitry Andric   uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
2900b57cec5SDimitry Andric   uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
2915ffd83dbSDimitry Andric   Expected<uint32_t> getSymbolFlags(DataRefImpl Symb) const override;
2920b57cec5SDimitry Andric   uint8_t getSymbolBinding(DataRefImpl Symb) const override;
2930b57cec5SDimitry Andric   uint8_t getSymbolOther(DataRefImpl Symb) const override;
2940b57cec5SDimitry Andric   uint8_t getSymbolELFType(DataRefImpl Symb) const override;
2950b57cec5SDimitry Andric   Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const override;
2960b57cec5SDimitry Andric   Expected<section_iterator> getSymbolSection(const Elf_Sym *Symb,
2970b57cec5SDimitry Andric                                               const Elf_Shdr *SymTab) const;
2980b57cec5SDimitry Andric   Expected<section_iterator> getSymbolSection(DataRefImpl Symb) const override;
2990b57cec5SDimitry Andric 
3000b57cec5SDimitry Andric   void moveSectionNext(DataRefImpl &Sec) const override;
3010b57cec5SDimitry Andric   Expected<StringRef> getSectionName(DataRefImpl Sec) const override;
3020b57cec5SDimitry Andric   uint64_t getSectionAddress(DataRefImpl Sec) const override;
3030b57cec5SDimitry Andric   uint64_t getSectionIndex(DataRefImpl Sec) const override;
3040b57cec5SDimitry Andric   uint64_t getSectionSize(DataRefImpl Sec) const override;
3050b57cec5SDimitry Andric   Expected<ArrayRef<uint8_t>>
3060b57cec5SDimitry Andric   getSectionContents(DataRefImpl Sec) const override;
3070b57cec5SDimitry Andric   uint64_t getSectionAlignment(DataRefImpl Sec) const override;
3080b57cec5SDimitry Andric   bool isSectionCompressed(DataRefImpl Sec) const override;
3090b57cec5SDimitry Andric   bool isSectionText(DataRefImpl Sec) const override;
3100b57cec5SDimitry Andric   bool isSectionData(DataRefImpl Sec) const override;
3110b57cec5SDimitry Andric   bool isSectionBSS(DataRefImpl Sec) const override;
3120b57cec5SDimitry Andric   bool isSectionVirtual(DataRefImpl Sec) const override;
3130b57cec5SDimitry Andric   bool isBerkeleyText(DataRefImpl Sec) const override;
3140b57cec5SDimitry Andric   bool isBerkeleyData(DataRefImpl Sec) const override;
315fe6060f1SDimitry Andric   bool isDebugSection(DataRefImpl Sec) const override;
3160b57cec5SDimitry Andric   relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
3170b57cec5SDimitry Andric   relocation_iterator section_rel_end(DataRefImpl Sec) const override;
3180b57cec5SDimitry Andric   std::vector<SectionRef> dynamic_relocation_sections() const override;
3198bcb0991SDimitry Andric   Expected<section_iterator>
3208bcb0991SDimitry Andric   getRelocatedSection(DataRefImpl Sec) const override;
3210b57cec5SDimitry Andric 
3220b57cec5SDimitry Andric   void moveRelocationNext(DataRefImpl &Rel) const override;
3230b57cec5SDimitry Andric   uint64_t getRelocationOffset(DataRefImpl Rel) const override;
3240b57cec5SDimitry Andric   symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
3250b57cec5SDimitry Andric   uint64_t getRelocationType(DataRefImpl Rel) const override;
3260b57cec5SDimitry Andric   void getRelocationTypeName(DataRefImpl Rel,
3270b57cec5SDimitry Andric                              SmallVectorImpl<char> &Result) const override;
3280b57cec5SDimitry Andric 
3290b57cec5SDimitry Andric   uint32_t getSectionType(DataRefImpl Sec) const override;
3300b57cec5SDimitry Andric   uint64_t getSectionFlags(DataRefImpl Sec) const override;
3310b57cec5SDimitry Andric   uint64_t getSectionOffset(DataRefImpl Sec) const override;
3320b57cec5SDimitry Andric   StringRef getRelocationTypeName(uint32_t Type) const;
3330b57cec5SDimitry Andric 
toDRI(const Elf_Shdr * SymTable,unsigned SymbolNum)3340b57cec5SDimitry Andric   DataRefImpl toDRI(const Elf_Shdr *SymTable, unsigned SymbolNum) const {
3350b57cec5SDimitry Andric     DataRefImpl DRI;
3360b57cec5SDimitry Andric     if (!SymTable) {
3370b57cec5SDimitry Andric       DRI.d.a = 0;
3380b57cec5SDimitry Andric       DRI.d.b = 0;
3390b57cec5SDimitry Andric       return DRI;
3400b57cec5SDimitry Andric     }
3410b57cec5SDimitry Andric     assert(SymTable->sh_type == ELF::SHT_SYMTAB ||
3420b57cec5SDimitry Andric            SymTable->sh_type == ELF::SHT_DYNSYM);
3430b57cec5SDimitry Andric 
3440b57cec5SDimitry Andric     auto SectionsOrErr = EF.sections();
3450b57cec5SDimitry Andric     if (!SectionsOrErr) {
3460b57cec5SDimitry Andric       DRI.d.a = 0;
3470b57cec5SDimitry Andric       DRI.d.b = 0;
3480b57cec5SDimitry Andric       return DRI;
3490b57cec5SDimitry Andric     }
3500b57cec5SDimitry Andric     uintptr_t SHT = reinterpret_cast<uintptr_t>((*SectionsOrErr).begin());
3510b57cec5SDimitry Andric     unsigned SymTableIndex =
3520b57cec5SDimitry Andric         (reinterpret_cast<uintptr_t>(SymTable) - SHT) / sizeof(Elf_Shdr);
3530b57cec5SDimitry Andric 
3540b57cec5SDimitry Andric     DRI.d.a = SymTableIndex;
3550b57cec5SDimitry Andric     DRI.d.b = SymbolNum;
3560b57cec5SDimitry Andric     return DRI;
3570b57cec5SDimitry Andric   }
3580b57cec5SDimitry Andric 
toELFShdrIter(DataRefImpl Sec)3590b57cec5SDimitry Andric   const Elf_Shdr *toELFShdrIter(DataRefImpl Sec) const {
3600b57cec5SDimitry Andric     return reinterpret_cast<const Elf_Shdr *>(Sec.p);
3610b57cec5SDimitry Andric   }
3620b57cec5SDimitry Andric 
toDRI(const Elf_Shdr * Sec)3630b57cec5SDimitry Andric   DataRefImpl toDRI(const Elf_Shdr *Sec) const {
3640b57cec5SDimitry Andric     DataRefImpl DRI;
3650b57cec5SDimitry Andric     DRI.p = reinterpret_cast<uintptr_t>(Sec);
3660b57cec5SDimitry Andric     return DRI;
3670b57cec5SDimitry Andric   }
3680b57cec5SDimitry Andric 
toDRI(const Elf_Dyn * Dyn)3690b57cec5SDimitry Andric   DataRefImpl toDRI(const Elf_Dyn *Dyn) const {
3700b57cec5SDimitry Andric     DataRefImpl DRI;
3710b57cec5SDimitry Andric     DRI.p = reinterpret_cast<uintptr_t>(Dyn);
3720b57cec5SDimitry Andric     return DRI;
3730b57cec5SDimitry Andric   }
3740b57cec5SDimitry Andric 
isExportedToOtherDSO(const Elf_Sym * ESym)3750b57cec5SDimitry Andric   bool isExportedToOtherDSO(const Elf_Sym *ESym) const {
3760b57cec5SDimitry Andric     unsigned char Binding = ESym->getBinding();
3770b57cec5SDimitry Andric     unsigned char Visibility = ESym->getVisibility();
3780b57cec5SDimitry Andric 
3790b57cec5SDimitry Andric     // A symbol is exported if its binding is either GLOBAL or WEAK, and its
3800b57cec5SDimitry Andric     // visibility is either DEFAULT or PROTECTED. All other symbols are not
3810b57cec5SDimitry Andric     // exported.
3820b57cec5SDimitry Andric     return (
3830b57cec5SDimitry Andric         (Binding == ELF::STB_GLOBAL || Binding == ELF::STB_WEAK ||
3840b57cec5SDimitry Andric          Binding == ELF::STB_GNU_UNIQUE) &&
3850b57cec5SDimitry Andric         (Visibility == ELF::STV_DEFAULT || Visibility == ELF::STV_PROTECTED));
3860b57cec5SDimitry Andric   }
3870b57cec5SDimitry Andric 
getBuildAttributes(ELFAttributeParser & Attributes)3885ffd83dbSDimitry Andric   Error getBuildAttributes(ELFAttributeParser &Attributes) const override {
3890b57cec5SDimitry Andric     auto SectionsOrErr = EF.sections();
3900b57cec5SDimitry Andric     if (!SectionsOrErr)
3910b57cec5SDimitry Andric       return SectionsOrErr.takeError();
3920b57cec5SDimitry Andric 
3930b57cec5SDimitry Andric     for (const Elf_Shdr &Sec : *SectionsOrErr) {
3945ffd83dbSDimitry Andric       if (Sec.sh_type == ELF::SHT_ARM_ATTRIBUTES ||
3955ffd83dbSDimitry Andric           Sec.sh_type == ELF::SHT_RISCV_ATTRIBUTES) {
396e8d8bef9SDimitry Andric         auto ErrorOrContents = EF.getSectionContents(Sec);
3970b57cec5SDimitry Andric         if (!ErrorOrContents)
3980b57cec5SDimitry Andric           return ErrorOrContents.takeError();
3990b57cec5SDimitry Andric 
4000b57cec5SDimitry Andric         auto Contents = ErrorOrContents.get();
4015ffd83dbSDimitry Andric         if (Contents[0] != ELFAttrs::Format_Version || Contents.size() == 1)
4020b57cec5SDimitry Andric           return Error::success();
4030b57cec5SDimitry Andric 
4045ffd83dbSDimitry Andric         if (Error E = Attributes.parse(Contents, ELFT::TargetEndianness))
4055ffd83dbSDimitry Andric           return E;
4060b57cec5SDimitry Andric         break;
4070b57cec5SDimitry Andric       }
4080b57cec5SDimitry Andric     }
4090b57cec5SDimitry Andric     return Error::success();
4100b57cec5SDimitry Andric   }
4110b57cec5SDimitry Andric 
4120b57cec5SDimitry Andric   // This flag is used for classof, to distinguish ELFObjectFile from
4130b57cec5SDimitry Andric   // its subclass. If more subclasses will be created, this flag will
4140b57cec5SDimitry Andric   // have to become an enum.
41506c3fb27SDimitry Andric   bool isDyldELFObject = false;
4160b57cec5SDimitry Andric 
4170b57cec5SDimitry Andric public:
4180b57cec5SDimitry Andric   ELFObjectFile(ELFObjectFile<ELFT> &&Other);
419e8d8bef9SDimitry Andric   static Expected<ELFObjectFile<ELFT>> create(MemoryBufferRef Object,
420e8d8bef9SDimitry Andric                                               bool InitContent = true);
4210b57cec5SDimitry Andric 
4220b57cec5SDimitry Andric   const Elf_Rel *getRel(DataRefImpl Rel) const;
4230b57cec5SDimitry Andric   const Elf_Rela *getRela(DataRefImpl Rela) const;
4240b57cec5SDimitry Andric 
getSymbol(DataRefImpl Sym)425e8d8bef9SDimitry Andric   Expected<const Elf_Sym *> getSymbol(DataRefImpl Sym) const {
426e8d8bef9SDimitry Andric     return EF.template getEntry<Elf_Sym>(Sym.d.a, Sym.d.b);
427e8d8bef9SDimitry Andric   }
428e8d8bef9SDimitry Andric 
429e8d8bef9SDimitry Andric   /// Get the relocation section that contains \a Rel.
getRelSection(DataRefImpl Rel)430e8d8bef9SDimitry Andric   const Elf_Shdr *getRelSection(DataRefImpl Rel) const {
431e8d8bef9SDimitry Andric     auto RelSecOrErr = EF.getSection(Rel.d.a);
432e8d8bef9SDimitry Andric     if (!RelSecOrErr)
433349cc55cSDimitry Andric       report_fatal_error(
434349cc55cSDimitry Andric           Twine(errorToErrorCode(RelSecOrErr.takeError()).message()));
435e8d8bef9SDimitry Andric     return *RelSecOrErr;
4360b57cec5SDimitry Andric   }
4370b57cec5SDimitry Andric 
getSection(DataRefImpl Sec)4380b57cec5SDimitry Andric   const Elf_Shdr *getSection(DataRefImpl Sec) const {
4390b57cec5SDimitry Andric     return reinterpret_cast<const Elf_Shdr *>(Sec.p);
4400b57cec5SDimitry Andric   }
4410b57cec5SDimitry Andric 
4420b57cec5SDimitry Andric   basic_symbol_iterator symbol_begin() const override;
4430b57cec5SDimitry Andric   basic_symbol_iterator symbol_end() const override;
4440b57cec5SDimitry Andric 
is64Bit()44506c3fb27SDimitry Andric   bool is64Bit() const override { return getBytesInAddress() == 8; }
44606c3fb27SDimitry Andric 
4470b57cec5SDimitry Andric   elf_symbol_iterator dynamic_symbol_begin() const;
4480b57cec5SDimitry Andric   elf_symbol_iterator dynamic_symbol_end() const;
4490b57cec5SDimitry Andric 
4500b57cec5SDimitry Andric   section_iterator section_begin() const override;
4510b57cec5SDimitry Andric   section_iterator section_end() const override;
4520b57cec5SDimitry Andric 
4530b57cec5SDimitry Andric   Expected<int64_t> getRelocationAddend(DataRefImpl Rel) const override;
4540b57cec5SDimitry Andric 
4550b57cec5SDimitry Andric   uint8_t getBytesInAddress() const override;
4560b57cec5SDimitry Andric   StringRef getFileFormatName() const override;
4570b57cec5SDimitry Andric   Triple::ArchType getArch() const override;
4581db9f3b2SDimitry Andric   Triple::OSType getOS() const override;
4590b57cec5SDimitry Andric   Expected<uint64_t> getStartAddress() const override;
4600b57cec5SDimitry Andric 
getPlatformFlags()461e8d8bef9SDimitry Andric   unsigned getPlatformFlags() const override { return EF.getHeader().e_flags; }
4620b57cec5SDimitry Andric 
getELFFile()463e8d8bef9SDimitry Andric   const ELFFile<ELFT> &getELFFile() const { return EF; }
4640b57cec5SDimitry Andric 
isDyldType()4650b57cec5SDimitry Andric   bool isDyldType() const { return isDyldELFObject; }
classof(const Binary * v)4660b57cec5SDimitry Andric   static bool classof(const Binary *v) {
4675f757f3fSDimitry Andric     return v->getType() ==
4685f757f3fSDimitry Andric            getELFType(ELFT::TargetEndianness == llvm::endianness::little,
4690b57cec5SDimitry Andric                       ELFT::Is64Bits);
4700b57cec5SDimitry Andric   }
4710b57cec5SDimitry Andric 
4720b57cec5SDimitry Andric   elf_symbol_iterator_range getDynamicSymbolIterators() const override;
4730b57cec5SDimitry Andric 
4740b57cec5SDimitry Andric   bool isRelocatableObject() const override;
475fcaf7f86SDimitry Andric 
createFakeSections()476fcaf7f86SDimitry Andric   void createFakeSections() { EF.createFakeSections(); }
4770b57cec5SDimitry Andric };
4780b57cec5SDimitry Andric 
4790b57cec5SDimitry Andric using ELF32LEObjectFile = ELFObjectFile<ELF32LE>;
4800b57cec5SDimitry Andric using ELF64LEObjectFile = ELFObjectFile<ELF64LE>;
4810b57cec5SDimitry Andric using ELF32BEObjectFile = ELFObjectFile<ELF32BE>;
4820b57cec5SDimitry Andric using ELF64BEObjectFile = ELFObjectFile<ELF64BE>;
4830b57cec5SDimitry Andric 
4840b57cec5SDimitry Andric template <class ELFT>
moveSymbolNext(DataRefImpl & Sym)4850b57cec5SDimitry Andric void ELFObjectFile<ELFT>::moveSymbolNext(DataRefImpl &Sym) const {
4860b57cec5SDimitry Andric   ++Sym.d.b;
4870b57cec5SDimitry Andric }
4880b57cec5SDimitry Andric 
initContent()489e8d8bef9SDimitry Andric template <class ELFT> Error ELFObjectFile<ELFT>::initContent() {
490e8d8bef9SDimitry Andric   auto SectionsOrErr = EF.sections();
491e8d8bef9SDimitry Andric   if (!SectionsOrErr)
492e8d8bef9SDimitry Andric     return SectionsOrErr.takeError();
493e8d8bef9SDimitry Andric 
494e8d8bef9SDimitry Andric   for (const Elf_Shdr &Sec : *SectionsOrErr) {
495e8d8bef9SDimitry Andric     switch (Sec.sh_type) {
496e8d8bef9SDimitry Andric     case ELF::SHT_DYNSYM: {
497e8d8bef9SDimitry Andric       if (!DotDynSymSec)
498e8d8bef9SDimitry Andric         DotDynSymSec = &Sec;
499e8d8bef9SDimitry Andric       break;
500e8d8bef9SDimitry Andric     }
501e8d8bef9SDimitry Andric     case ELF::SHT_SYMTAB: {
502e8d8bef9SDimitry Andric       if (!DotSymtabSec)
503e8d8bef9SDimitry Andric         DotSymtabSec = &Sec;
504e8d8bef9SDimitry Andric       break;
505e8d8bef9SDimitry Andric     }
506e8d8bef9SDimitry Andric     case ELF::SHT_SYMTAB_SHNDX: {
507e8d8bef9SDimitry Andric       if (!DotSymtabShndxSec)
508e8d8bef9SDimitry Andric         DotSymtabShndxSec = &Sec;
509e8d8bef9SDimitry Andric       break;
510e8d8bef9SDimitry Andric     }
511e8d8bef9SDimitry Andric     }
512e8d8bef9SDimitry Andric   }
513e8d8bef9SDimitry Andric 
514e8d8bef9SDimitry Andric   ContentValid = true;
515e8d8bef9SDimitry Andric   return Error::success();
516e8d8bef9SDimitry Andric }
517e8d8bef9SDimitry Andric 
5180b57cec5SDimitry Andric template <class ELFT>
getSymbolName(DataRefImpl Sym)5190b57cec5SDimitry Andric Expected<StringRef> ELFObjectFile<ELFT>::getSymbolName(DataRefImpl Sym) const {
520e8d8bef9SDimitry Andric   Expected<const Elf_Sym *> SymOrErr = getSymbol(Sym);
521e8d8bef9SDimitry Andric   if (!SymOrErr)
522e8d8bef9SDimitry Andric     return SymOrErr.takeError();
5230b57cec5SDimitry Andric   auto SymTabOrErr = EF.getSection(Sym.d.a);
5240b57cec5SDimitry Andric   if (!SymTabOrErr)
5250b57cec5SDimitry Andric     return SymTabOrErr.takeError();
5260b57cec5SDimitry Andric   const Elf_Shdr *SymTableSec = *SymTabOrErr;
5270b57cec5SDimitry Andric   auto StrTabOrErr = EF.getSection(SymTableSec->sh_link);
5280b57cec5SDimitry Andric   if (!StrTabOrErr)
5290b57cec5SDimitry Andric     return StrTabOrErr.takeError();
5300b57cec5SDimitry Andric   const Elf_Shdr *StringTableSec = *StrTabOrErr;
531e8d8bef9SDimitry Andric   auto SymStrTabOrErr = EF.getStringTable(*StringTableSec);
5320b57cec5SDimitry Andric   if (!SymStrTabOrErr)
5330b57cec5SDimitry Andric     return SymStrTabOrErr.takeError();
534e8d8bef9SDimitry Andric   Expected<StringRef> Name = (*SymOrErr)->getName(*SymStrTabOrErr);
5358bcb0991SDimitry Andric   if (Name && !Name->empty())
5368bcb0991SDimitry Andric     return Name;
5370b57cec5SDimitry Andric 
5380b57cec5SDimitry Andric   // If the symbol name is empty use the section name.
539e8d8bef9SDimitry Andric   if ((*SymOrErr)->getType() == ELF::STT_SECTION) {
54006c3fb27SDimitry Andric     Expected<section_iterator> SecOrErr = getSymbolSection(Sym);
54106c3fb27SDimitry Andric     if (SecOrErr)
5428bcb0991SDimitry Andric       return (*SecOrErr)->getName();
54306c3fb27SDimitry Andric     return SecOrErr.takeError();
5440b57cec5SDimitry Andric   }
5450b57cec5SDimitry Andric   return Name;
5460b57cec5SDimitry Andric }
5470b57cec5SDimitry Andric 
5480b57cec5SDimitry Andric template <class ELFT>
getSectionFlags(DataRefImpl Sec)5490b57cec5SDimitry Andric uint64_t ELFObjectFile<ELFT>::getSectionFlags(DataRefImpl Sec) const {
5500b57cec5SDimitry Andric   return getSection(Sec)->sh_flags;
5510b57cec5SDimitry Andric }
5520b57cec5SDimitry Andric 
5530b57cec5SDimitry Andric template <class ELFT>
getSectionType(DataRefImpl Sec)5540b57cec5SDimitry Andric uint32_t ELFObjectFile<ELFT>::getSectionType(DataRefImpl Sec) const {
5550b57cec5SDimitry Andric   return getSection(Sec)->sh_type;
5560b57cec5SDimitry Andric }
5570b57cec5SDimitry Andric 
5580b57cec5SDimitry Andric template <class ELFT>
getSectionOffset(DataRefImpl Sec)5590b57cec5SDimitry Andric uint64_t ELFObjectFile<ELFT>::getSectionOffset(DataRefImpl Sec) const {
5600b57cec5SDimitry Andric   return getSection(Sec)->sh_offset;
5610b57cec5SDimitry Andric }
5620b57cec5SDimitry Andric 
5630b57cec5SDimitry Andric template <class ELFT>
getSymbolValueImpl(DataRefImpl Symb)5640b57cec5SDimitry Andric uint64_t ELFObjectFile<ELFT>::getSymbolValueImpl(DataRefImpl Symb) const {
565e8d8bef9SDimitry Andric   Expected<const Elf_Sym *> SymOrErr = getSymbol(Symb);
566e8d8bef9SDimitry Andric   if (!SymOrErr)
567e8d8bef9SDimitry Andric     report_fatal_error(SymOrErr.takeError());
568e8d8bef9SDimitry Andric 
569e8d8bef9SDimitry Andric   uint64_t Ret = (*SymOrErr)->st_value;
570e8d8bef9SDimitry Andric   if ((*SymOrErr)->st_shndx == ELF::SHN_ABS)
5710b57cec5SDimitry Andric     return Ret;
5720b57cec5SDimitry Andric 
573e8d8bef9SDimitry Andric   const Elf_Ehdr &Header = EF.getHeader();
5740b57cec5SDimitry Andric   // Clear the ARM/Thumb or microMIPS indicator flag.
575e8d8bef9SDimitry Andric   if ((Header.e_machine == ELF::EM_ARM || Header.e_machine == ELF::EM_MIPS) &&
576e8d8bef9SDimitry Andric       (*SymOrErr)->getType() == ELF::STT_FUNC)
5770b57cec5SDimitry Andric     Ret &= ~1;
5780b57cec5SDimitry Andric 
5790b57cec5SDimitry Andric   return Ret;
5800b57cec5SDimitry Andric }
5810b57cec5SDimitry Andric 
5820b57cec5SDimitry Andric template <class ELFT>
5830b57cec5SDimitry Andric Expected<uint64_t>
getSymbolAddress(DataRefImpl Symb)5840b57cec5SDimitry Andric ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb) const {
5855ffd83dbSDimitry Andric   Expected<uint64_t> SymbolValueOrErr = getSymbolValue(Symb);
5865ffd83dbSDimitry Andric   if (!SymbolValueOrErr)
5875ffd83dbSDimitry Andric     // TODO: Test this error.
5885ffd83dbSDimitry Andric     return SymbolValueOrErr.takeError();
5895ffd83dbSDimitry Andric 
5905ffd83dbSDimitry Andric   uint64_t Result = *SymbolValueOrErr;
591e8d8bef9SDimitry Andric   Expected<const Elf_Sym *> SymOrErr = getSymbol(Symb);
592e8d8bef9SDimitry Andric   if (!SymOrErr)
593e8d8bef9SDimitry Andric     return SymOrErr.takeError();
594e8d8bef9SDimitry Andric 
595e8d8bef9SDimitry Andric   switch ((*SymOrErr)->st_shndx) {
5960b57cec5SDimitry Andric   case ELF::SHN_COMMON:
5970b57cec5SDimitry Andric   case ELF::SHN_UNDEF:
5980b57cec5SDimitry Andric   case ELF::SHN_ABS:
5990b57cec5SDimitry Andric     return Result;
6000b57cec5SDimitry Andric   }
6010b57cec5SDimitry Andric 
6020b57cec5SDimitry Andric   auto SymTabOrErr = EF.getSection(Symb.d.a);
6030b57cec5SDimitry Andric   if (!SymTabOrErr)
6040b57cec5SDimitry Andric     return SymTabOrErr.takeError();
6050b57cec5SDimitry Andric 
606e8d8bef9SDimitry Andric   if (EF.getHeader().e_type == ELF::ET_REL) {
607e8d8bef9SDimitry Andric     ArrayRef<Elf_Word> ShndxTable;
608e8d8bef9SDimitry Andric     if (DotSymtabShndxSec) {
609e8d8bef9SDimitry Andric       // TODO: Test this error.
610e8d8bef9SDimitry Andric       if (Expected<ArrayRef<Elf_Word>> ShndxTableOrErr =
611e8d8bef9SDimitry Andric               EF.getSHNDXTable(*DotSymtabShndxSec))
612e8d8bef9SDimitry Andric         ShndxTable = *ShndxTableOrErr;
613e8d8bef9SDimitry Andric       else
614e8d8bef9SDimitry Andric         return ShndxTableOrErr.takeError();
615e8d8bef9SDimitry Andric     }
616e8d8bef9SDimitry Andric 
617e8d8bef9SDimitry Andric     Expected<const Elf_Shdr *> SectionOrErr =
618e8d8bef9SDimitry Andric         EF.getSection(**SymOrErr, *SymTabOrErr, ShndxTable);
6190b57cec5SDimitry Andric     if (!SectionOrErr)
6200b57cec5SDimitry Andric       return SectionOrErr.takeError();
6210b57cec5SDimitry Andric     const Elf_Shdr *Section = *SectionOrErr;
6220b57cec5SDimitry Andric     if (Section)
6230b57cec5SDimitry Andric       Result += Section->sh_addr;
6240b57cec5SDimitry Andric   }
6250b57cec5SDimitry Andric 
6260b57cec5SDimitry Andric   return Result;
6270b57cec5SDimitry Andric }
6280b57cec5SDimitry Andric 
6290b57cec5SDimitry Andric template <class ELFT>
getSymbolAlignment(DataRefImpl Symb)6300b57cec5SDimitry Andric uint32_t ELFObjectFile<ELFT>::getSymbolAlignment(DataRefImpl Symb) const {
631e8d8bef9SDimitry Andric   Expected<const Elf_Sym *> SymOrErr = getSymbol(Symb);
632e8d8bef9SDimitry Andric   if (!SymOrErr)
633e8d8bef9SDimitry Andric     report_fatal_error(SymOrErr.takeError());
634e8d8bef9SDimitry Andric   if ((*SymOrErr)->st_shndx == ELF::SHN_COMMON)
635e8d8bef9SDimitry Andric     return (*SymOrErr)->st_value;
6360b57cec5SDimitry Andric   return 0;
6370b57cec5SDimitry Andric }
6380b57cec5SDimitry Andric 
6390b57cec5SDimitry Andric template <class ELFT>
getEMachine()6400b57cec5SDimitry Andric uint16_t ELFObjectFile<ELFT>::getEMachine() const {
641e8d8bef9SDimitry Andric   return EF.getHeader().e_machine;
6420b57cec5SDimitry Andric }
6430b57cec5SDimitry Andric 
getEType()6440b57cec5SDimitry Andric template <class ELFT> uint16_t ELFObjectFile<ELFT>::getEType() const {
645e8d8bef9SDimitry Andric   return EF.getHeader().e_type;
6460b57cec5SDimitry Andric }
6470b57cec5SDimitry Andric 
6480b57cec5SDimitry Andric template <class ELFT>
getSymbolSize(DataRefImpl Sym)6490b57cec5SDimitry Andric uint64_t ELFObjectFile<ELFT>::getSymbolSize(DataRefImpl Sym) const {
650e8d8bef9SDimitry Andric   Expected<const Elf_Sym *> SymOrErr = getSymbol(Sym);
651e8d8bef9SDimitry Andric   if (!SymOrErr)
652e8d8bef9SDimitry Andric     report_fatal_error(SymOrErr.takeError());
653e8d8bef9SDimitry Andric   return (*SymOrErr)->st_size;
6540b57cec5SDimitry Andric }
6550b57cec5SDimitry Andric 
6560b57cec5SDimitry Andric template <class ELFT>
getCommonSymbolSizeImpl(DataRefImpl Symb)6570b57cec5SDimitry Andric uint64_t ELFObjectFile<ELFT>::getCommonSymbolSizeImpl(DataRefImpl Symb) const {
658e8d8bef9SDimitry Andric   return getSymbolSize(Symb);
6590b57cec5SDimitry Andric }
6600b57cec5SDimitry Andric 
6610b57cec5SDimitry Andric template <class ELFT>
getSymbolBinding(DataRefImpl Symb)6620b57cec5SDimitry Andric uint8_t ELFObjectFile<ELFT>::getSymbolBinding(DataRefImpl Symb) const {
663e8d8bef9SDimitry Andric   Expected<const Elf_Sym *> SymOrErr = getSymbol(Symb);
664e8d8bef9SDimitry Andric   if (!SymOrErr)
665e8d8bef9SDimitry Andric     report_fatal_error(SymOrErr.takeError());
666e8d8bef9SDimitry Andric   return (*SymOrErr)->getBinding();
6670b57cec5SDimitry Andric }
6680b57cec5SDimitry Andric 
6690b57cec5SDimitry Andric template <class ELFT>
getSymbolOther(DataRefImpl Symb)6700b57cec5SDimitry Andric uint8_t ELFObjectFile<ELFT>::getSymbolOther(DataRefImpl Symb) const {
671e8d8bef9SDimitry Andric   Expected<const Elf_Sym *> SymOrErr = getSymbol(Symb);
672e8d8bef9SDimitry Andric   if (!SymOrErr)
673e8d8bef9SDimitry Andric     report_fatal_error(SymOrErr.takeError());
674e8d8bef9SDimitry Andric   return (*SymOrErr)->st_other;
6750b57cec5SDimitry Andric }
6760b57cec5SDimitry Andric 
6770b57cec5SDimitry Andric template <class ELFT>
getSymbolELFType(DataRefImpl Symb)6780b57cec5SDimitry Andric uint8_t ELFObjectFile<ELFT>::getSymbolELFType(DataRefImpl Symb) const {
679e8d8bef9SDimitry Andric   Expected<const Elf_Sym *> SymOrErr = getSymbol(Symb);
680e8d8bef9SDimitry Andric   if (!SymOrErr)
681e8d8bef9SDimitry Andric     report_fatal_error(SymOrErr.takeError());
682e8d8bef9SDimitry Andric   return (*SymOrErr)->getType();
6830b57cec5SDimitry Andric }
6840b57cec5SDimitry Andric 
6850b57cec5SDimitry Andric template <class ELFT>
6860b57cec5SDimitry Andric Expected<SymbolRef::Type>
getSymbolType(DataRefImpl Symb)6870b57cec5SDimitry Andric ELFObjectFile<ELFT>::getSymbolType(DataRefImpl Symb) const {
688e8d8bef9SDimitry Andric   Expected<const Elf_Sym *> SymOrErr = getSymbol(Symb);
689e8d8bef9SDimitry Andric   if (!SymOrErr)
690e8d8bef9SDimitry Andric     return SymOrErr.takeError();
6910b57cec5SDimitry Andric 
692e8d8bef9SDimitry Andric   switch ((*SymOrErr)->getType()) {
6930b57cec5SDimitry Andric   case ELF::STT_NOTYPE:
6940b57cec5SDimitry Andric     return SymbolRef::ST_Unknown;
6950b57cec5SDimitry Andric   case ELF::STT_SECTION:
6960b57cec5SDimitry Andric     return SymbolRef::ST_Debug;
6970b57cec5SDimitry Andric   case ELF::STT_FILE:
6980b57cec5SDimitry Andric     return SymbolRef::ST_File;
6990b57cec5SDimitry Andric   case ELF::STT_FUNC:
7000b57cec5SDimitry Andric     return SymbolRef::ST_Function;
7010b57cec5SDimitry Andric   case ELF::STT_OBJECT:
7020b57cec5SDimitry Andric   case ELF::STT_COMMON:
7030b57cec5SDimitry Andric     return SymbolRef::ST_Data;
704fe6060f1SDimitry Andric   case ELF::STT_TLS:
7050b57cec5SDimitry Andric   default:
7060b57cec5SDimitry Andric     return SymbolRef::ST_Other;
7070b57cec5SDimitry Andric   }
7080b57cec5SDimitry Andric }
7090b57cec5SDimitry Andric 
7100b57cec5SDimitry Andric template <class ELFT>
getSymbolFlags(DataRefImpl Sym)7115ffd83dbSDimitry Andric Expected<uint32_t> ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Sym) const {
712e8d8bef9SDimitry Andric   Expected<const Elf_Sym *> SymOrErr = getSymbol(Sym);
713e8d8bef9SDimitry Andric   if (!SymOrErr)
714e8d8bef9SDimitry Andric     return SymOrErr.takeError();
7150b57cec5SDimitry Andric 
716e8d8bef9SDimitry Andric   const Elf_Sym *ESym = *SymOrErr;
7170b57cec5SDimitry Andric   uint32_t Result = SymbolRef::SF_None;
7180b57cec5SDimitry Andric 
7190b57cec5SDimitry Andric   if (ESym->getBinding() != ELF::STB_LOCAL)
7200b57cec5SDimitry Andric     Result |= SymbolRef::SF_Global;
7210b57cec5SDimitry Andric 
7220b57cec5SDimitry Andric   if (ESym->getBinding() == ELF::STB_WEAK)
7230b57cec5SDimitry Andric     Result |= SymbolRef::SF_Weak;
7240b57cec5SDimitry Andric 
7250b57cec5SDimitry Andric   if (ESym->st_shndx == ELF::SHN_ABS)
7260b57cec5SDimitry Andric     Result |= SymbolRef::SF_Absolute;
7270b57cec5SDimitry Andric 
7280b57cec5SDimitry Andric   if (ESym->getType() == ELF::STT_FILE || ESym->getType() == ELF::STT_SECTION)
7290b57cec5SDimitry Andric     Result |= SymbolRef::SF_FormatSpecific;
7300b57cec5SDimitry Andric 
7315ffd83dbSDimitry Andric   if (Expected<typename ELFT::SymRange> SymbolsOrErr =
7325ffd83dbSDimitry Andric           EF.symbols(DotSymtabSec)) {
7335ffd83dbSDimitry Andric     // Set the SF_FormatSpecific flag for the 0-index null symbol.
7345ffd83dbSDimitry Andric     if (ESym == SymbolsOrErr->begin())
7350b57cec5SDimitry Andric       Result |= SymbolRef::SF_FormatSpecific;
7365ffd83dbSDimitry Andric   } else
7375ffd83dbSDimitry Andric     // TODO: Test this error.
7385ffd83dbSDimitry Andric     return SymbolsOrErr.takeError();
7395ffd83dbSDimitry Andric 
7405ffd83dbSDimitry Andric   if (Expected<typename ELFT::SymRange> SymbolsOrErr =
7415ffd83dbSDimitry Andric           EF.symbols(DotDynSymSec)) {
7425ffd83dbSDimitry Andric     // Set the SF_FormatSpecific flag for the 0-index null symbol.
7435ffd83dbSDimitry Andric     if (ESym == SymbolsOrErr->begin())
7440b57cec5SDimitry Andric       Result |= SymbolRef::SF_FormatSpecific;
7455ffd83dbSDimitry Andric   } else
7465ffd83dbSDimitry Andric     // TODO: Test this error.
7475ffd83dbSDimitry Andric     return SymbolsOrErr.takeError();
7480b57cec5SDimitry Andric 
749fe6060f1SDimitry Andric   if (EF.getHeader().e_machine == ELF::EM_AARCH64) {
750fe6060f1SDimitry Andric     if (Expected<StringRef> NameOrErr = getSymbolName(Sym)) {
751fe6060f1SDimitry Andric       StringRef Name = *NameOrErr;
7525f757f3fSDimitry Andric       if (Name.starts_with("$d") || Name.starts_with("$x"))
753fe6060f1SDimitry Andric         Result |= SymbolRef::SF_FormatSpecific;
754fe6060f1SDimitry Andric     } else {
755fe6060f1SDimitry Andric       // TODO: Actually report errors helpfully.
756fe6060f1SDimitry Andric       consumeError(NameOrErr.takeError());
757fe6060f1SDimitry Andric     }
758fe6060f1SDimitry Andric   } else if (EF.getHeader().e_machine == ELF::EM_ARM) {
7590b57cec5SDimitry Andric     if (Expected<StringRef> NameOrErr = getSymbolName(Sym)) {
7600b57cec5SDimitry Andric       StringRef Name = *NameOrErr;
761349cc55cSDimitry Andric       // TODO Investigate why empty name symbols need to be marked.
7625f757f3fSDimitry Andric       if (Name.empty() || Name.starts_with("$d") || Name.starts_with("$t") ||
7635f757f3fSDimitry Andric           Name.starts_with("$a"))
7640b57cec5SDimitry Andric         Result |= SymbolRef::SF_FormatSpecific;
7650b57cec5SDimitry Andric     } else {
7660b57cec5SDimitry Andric       // TODO: Actually report errors helpfully.
7670b57cec5SDimitry Andric       consumeError(NameOrErr.takeError());
7680b57cec5SDimitry Andric     }
7690b57cec5SDimitry Andric     if (ESym->getType() == ELF::STT_FUNC && (ESym->st_value & 1) == 1)
7700b57cec5SDimitry Andric       Result |= SymbolRef::SF_Thumb;
7715f757f3fSDimitry Andric   } else if (EF.getHeader().e_machine == ELF::EM_CSKY) {
7725f757f3fSDimitry Andric     if (Expected<StringRef> NameOrErr = getSymbolName(Sym)) {
7735f757f3fSDimitry Andric       StringRef Name = *NameOrErr;
7745f757f3fSDimitry Andric       if (Name.starts_with("$d") || Name.starts_with("$t"))
7755f757f3fSDimitry Andric         Result |= SymbolRef::SF_FormatSpecific;
7765f757f3fSDimitry Andric     } else {
7775f757f3fSDimitry Andric       // TODO: Actually report errors helpfully.
7785f757f3fSDimitry Andric       consumeError(NameOrErr.takeError());
7795f757f3fSDimitry Andric     }
780fe6060f1SDimitry Andric   } else if (EF.getHeader().e_machine == ELF::EM_RISCV) {
781fe6060f1SDimitry Andric     if (Expected<StringRef> NameOrErr = getSymbolName(Sym)) {
7825f757f3fSDimitry Andric       StringRef Name = *NameOrErr;
7835f757f3fSDimitry Andric       // Mark empty name symbols (used for label differences) and mapping
7845f757f3fSDimitry Andric       // symbols.
7855f757f3fSDimitry Andric       if (Name.empty() || Name.starts_with("$d") || Name.starts_with("$x"))
786fe6060f1SDimitry Andric         Result |= SymbolRef::SF_FormatSpecific;
787fe6060f1SDimitry Andric     } else {
788fe6060f1SDimitry Andric       // TODO: Actually report errors helpfully.
789fe6060f1SDimitry Andric       consumeError(NameOrErr.takeError());
790fe6060f1SDimitry Andric     }
7910b57cec5SDimitry Andric   }
7920b57cec5SDimitry Andric 
7930b57cec5SDimitry Andric   if (ESym->st_shndx == ELF::SHN_UNDEF)
7940b57cec5SDimitry Andric     Result |= SymbolRef::SF_Undefined;
7950b57cec5SDimitry Andric 
7960b57cec5SDimitry Andric   if (ESym->getType() == ELF::STT_COMMON || ESym->st_shndx == ELF::SHN_COMMON)
7970b57cec5SDimitry Andric     Result |= SymbolRef::SF_Common;
7980b57cec5SDimitry Andric 
7990b57cec5SDimitry Andric   if (isExportedToOtherDSO(ESym))
8000b57cec5SDimitry Andric     Result |= SymbolRef::SF_Exported;
8010b57cec5SDimitry Andric 
802bdd1243dSDimitry Andric   if (ESym->getType() == ELF::STT_GNU_IFUNC)
803bdd1243dSDimitry Andric     Result |= SymbolRef::SF_Indirect;
804bdd1243dSDimitry Andric 
8050b57cec5SDimitry Andric   if (ESym->getVisibility() == ELF::STV_HIDDEN)
8060b57cec5SDimitry Andric     Result |= SymbolRef::SF_Hidden;
8070b57cec5SDimitry Andric 
8080b57cec5SDimitry Andric   return Result;
8090b57cec5SDimitry Andric }
8100b57cec5SDimitry Andric 
8110b57cec5SDimitry Andric template <class ELFT>
8120b57cec5SDimitry Andric Expected<section_iterator>
getSymbolSection(const Elf_Sym * ESym,const Elf_Shdr * SymTab)8130b57cec5SDimitry Andric ELFObjectFile<ELFT>::getSymbolSection(const Elf_Sym *ESym,
8140b57cec5SDimitry Andric                                       const Elf_Shdr *SymTab) const {
815e8d8bef9SDimitry Andric   ArrayRef<Elf_Word> ShndxTable;
816e8d8bef9SDimitry Andric   if (DotSymtabShndxSec) {
817e8d8bef9SDimitry Andric     // TODO: Test this error.
818e8d8bef9SDimitry Andric     Expected<ArrayRef<Elf_Word>> ShndxTableOrErr =
819e8d8bef9SDimitry Andric         EF.getSHNDXTable(*DotSymtabShndxSec);
820e8d8bef9SDimitry Andric     if (!ShndxTableOrErr)
821e8d8bef9SDimitry Andric       return ShndxTableOrErr.takeError();
822e8d8bef9SDimitry Andric     ShndxTable = *ShndxTableOrErr;
823e8d8bef9SDimitry Andric   }
824e8d8bef9SDimitry Andric 
825e8d8bef9SDimitry Andric   auto ESecOrErr = EF.getSection(*ESym, SymTab, ShndxTable);
8260b57cec5SDimitry Andric   if (!ESecOrErr)
8270b57cec5SDimitry Andric     return ESecOrErr.takeError();
8280b57cec5SDimitry Andric 
8290b57cec5SDimitry Andric   const Elf_Shdr *ESec = *ESecOrErr;
8300b57cec5SDimitry Andric   if (!ESec)
8310b57cec5SDimitry Andric     return section_end();
8320b57cec5SDimitry Andric 
8330b57cec5SDimitry Andric   DataRefImpl Sec;
8340b57cec5SDimitry Andric   Sec.p = reinterpret_cast<intptr_t>(ESec);
8350b57cec5SDimitry Andric   return section_iterator(SectionRef(Sec, this));
8360b57cec5SDimitry Andric }
8370b57cec5SDimitry Andric 
8380b57cec5SDimitry Andric template <class ELFT>
8390b57cec5SDimitry Andric Expected<section_iterator>
getSymbolSection(DataRefImpl Symb)8400b57cec5SDimitry Andric ELFObjectFile<ELFT>::getSymbolSection(DataRefImpl Symb) const {
841e8d8bef9SDimitry Andric   Expected<const Elf_Sym *> SymOrErr = getSymbol(Symb);
842e8d8bef9SDimitry Andric   if (!SymOrErr)
843e8d8bef9SDimitry Andric     return SymOrErr.takeError();
844e8d8bef9SDimitry Andric 
8450b57cec5SDimitry Andric   auto SymTabOrErr = EF.getSection(Symb.d.a);
8460b57cec5SDimitry Andric   if (!SymTabOrErr)
8470b57cec5SDimitry Andric     return SymTabOrErr.takeError();
848e8d8bef9SDimitry Andric   return getSymbolSection(*SymOrErr, *SymTabOrErr);
8490b57cec5SDimitry Andric }
8500b57cec5SDimitry Andric 
8510b57cec5SDimitry Andric template <class ELFT>
moveSectionNext(DataRefImpl & Sec)8520b57cec5SDimitry Andric void ELFObjectFile<ELFT>::moveSectionNext(DataRefImpl &Sec) const {
8530b57cec5SDimitry Andric   const Elf_Shdr *ESec = getSection(Sec);
8540b57cec5SDimitry Andric   Sec = toDRI(++ESec);
8550b57cec5SDimitry Andric }
8560b57cec5SDimitry Andric 
8570b57cec5SDimitry Andric template <class ELFT>
getSectionName(DataRefImpl Sec)8580b57cec5SDimitry Andric Expected<StringRef> ELFObjectFile<ELFT>::getSectionName(DataRefImpl Sec) const {
859e8d8bef9SDimitry Andric   return EF.getSectionName(*getSection(Sec));
8600b57cec5SDimitry Andric }
8610b57cec5SDimitry Andric 
8620b57cec5SDimitry Andric template <class ELFT>
getSectionAddress(DataRefImpl Sec)8630b57cec5SDimitry Andric uint64_t ELFObjectFile<ELFT>::getSectionAddress(DataRefImpl Sec) const {
8640b57cec5SDimitry Andric   return getSection(Sec)->sh_addr;
8650b57cec5SDimitry Andric }
8660b57cec5SDimitry Andric 
8670b57cec5SDimitry Andric template <class ELFT>
getSectionIndex(DataRefImpl Sec)8680b57cec5SDimitry Andric uint64_t ELFObjectFile<ELFT>::getSectionIndex(DataRefImpl Sec) const {
8690b57cec5SDimitry Andric   auto SectionsOrErr = EF.sections();
8700b57cec5SDimitry Andric   handleAllErrors(std::move(SectionsOrErr.takeError()),
8710b57cec5SDimitry Andric                   [](const ErrorInfoBase &) {
8720b57cec5SDimitry Andric                     llvm_unreachable("unable to get section index");
8730b57cec5SDimitry Andric                   });
8740b57cec5SDimitry Andric   const Elf_Shdr *First = SectionsOrErr->begin();
8750b57cec5SDimitry Andric   return getSection(Sec) - First;
8760b57cec5SDimitry Andric }
8770b57cec5SDimitry Andric 
8780b57cec5SDimitry Andric template <class ELFT>
getSectionSize(DataRefImpl Sec)8790b57cec5SDimitry Andric uint64_t ELFObjectFile<ELFT>::getSectionSize(DataRefImpl Sec) const {
8800b57cec5SDimitry Andric   return getSection(Sec)->sh_size;
8810b57cec5SDimitry Andric }
8820b57cec5SDimitry Andric 
8830b57cec5SDimitry Andric template <class ELFT>
8840b57cec5SDimitry Andric Expected<ArrayRef<uint8_t>>
getSectionContents(DataRefImpl Sec)8850b57cec5SDimitry Andric ELFObjectFile<ELFT>::getSectionContents(DataRefImpl Sec) const {
8860b57cec5SDimitry Andric   const Elf_Shdr *EShdr = getSection(Sec);
887480093f4SDimitry Andric   if (EShdr->sh_type == ELF::SHT_NOBITS)
888bdd1243dSDimitry Andric     return ArrayRef((const uint8_t *)base(), (size_t)0);
8895ffd83dbSDimitry Andric   if (Error E =
8900b57cec5SDimitry Andric           checkOffset(getMemoryBufferRef(),
8910b57cec5SDimitry Andric                       (uintptr_t)base() + EShdr->sh_offset, EShdr->sh_size))
8925ffd83dbSDimitry Andric     return std::move(E);
893bdd1243dSDimitry Andric   return ArrayRef((const uint8_t *)base() + EShdr->sh_offset, EShdr->sh_size);
8940b57cec5SDimitry Andric }
8950b57cec5SDimitry Andric 
8960b57cec5SDimitry Andric template <class ELFT>
getSectionAlignment(DataRefImpl Sec)8970b57cec5SDimitry Andric uint64_t ELFObjectFile<ELFT>::getSectionAlignment(DataRefImpl Sec) const {
8980b57cec5SDimitry Andric   return getSection(Sec)->sh_addralign;
8990b57cec5SDimitry Andric }
9000b57cec5SDimitry Andric 
9010b57cec5SDimitry Andric template <class ELFT>
isSectionCompressed(DataRefImpl Sec)9020b57cec5SDimitry Andric bool ELFObjectFile<ELFT>::isSectionCompressed(DataRefImpl Sec) const {
9030b57cec5SDimitry Andric   return getSection(Sec)->sh_flags & ELF::SHF_COMPRESSED;
9040b57cec5SDimitry Andric }
9050b57cec5SDimitry Andric 
9060b57cec5SDimitry Andric template <class ELFT>
isSectionText(DataRefImpl Sec)9070b57cec5SDimitry Andric bool ELFObjectFile<ELFT>::isSectionText(DataRefImpl Sec) const {
9080b57cec5SDimitry Andric   return getSection(Sec)->sh_flags & ELF::SHF_EXECINSTR;
9090b57cec5SDimitry Andric }
9100b57cec5SDimitry Andric 
9110b57cec5SDimitry Andric template <class ELFT>
isSectionData(DataRefImpl Sec)9120b57cec5SDimitry Andric bool ELFObjectFile<ELFT>::isSectionData(DataRefImpl Sec) const {
9130b57cec5SDimitry Andric   const Elf_Shdr *EShdr = getSection(Sec);
9140b57cec5SDimitry Andric   return EShdr->sh_type == ELF::SHT_PROGBITS &&
9150b57cec5SDimitry Andric          EShdr->sh_flags & ELF::SHF_ALLOC &&
9160b57cec5SDimitry Andric          !(EShdr->sh_flags & ELF::SHF_EXECINSTR);
9170b57cec5SDimitry Andric }
9180b57cec5SDimitry Andric 
9190b57cec5SDimitry Andric template <class ELFT>
isSectionBSS(DataRefImpl Sec)9200b57cec5SDimitry Andric bool ELFObjectFile<ELFT>::isSectionBSS(DataRefImpl Sec) const {
9210b57cec5SDimitry Andric   const Elf_Shdr *EShdr = getSection(Sec);
9220b57cec5SDimitry Andric   return EShdr->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) &&
9230b57cec5SDimitry Andric          EShdr->sh_type == ELF::SHT_NOBITS;
9240b57cec5SDimitry Andric }
9250b57cec5SDimitry Andric 
9260b57cec5SDimitry Andric template <class ELFT>
9270b57cec5SDimitry Andric std::vector<SectionRef>
dynamic_relocation_sections()9280b57cec5SDimitry Andric ELFObjectFile<ELFT>::dynamic_relocation_sections() const {
9290b57cec5SDimitry Andric   std::vector<SectionRef> Res;
9300b57cec5SDimitry Andric   std::vector<uintptr_t> Offsets;
9310b57cec5SDimitry Andric 
9320b57cec5SDimitry Andric   auto SectionsOrErr = EF.sections();
9330b57cec5SDimitry Andric   if (!SectionsOrErr)
9340b57cec5SDimitry Andric     return Res;
9350b57cec5SDimitry Andric 
9360b57cec5SDimitry Andric   for (const Elf_Shdr &Sec : *SectionsOrErr) {
9370b57cec5SDimitry Andric     if (Sec.sh_type != ELF::SHT_DYNAMIC)
9380b57cec5SDimitry Andric       continue;
9390b57cec5SDimitry Andric     Elf_Dyn *Dynamic =
9400b57cec5SDimitry Andric         reinterpret_cast<Elf_Dyn *>((uintptr_t)base() + Sec.sh_offset);
9410b57cec5SDimitry Andric     for (; Dynamic->d_tag != ELF::DT_NULL; Dynamic++) {
9420b57cec5SDimitry Andric       if (Dynamic->d_tag == ELF::DT_REL || Dynamic->d_tag == ELF::DT_RELA ||
9430b57cec5SDimitry Andric           Dynamic->d_tag == ELF::DT_JMPREL) {
9440b57cec5SDimitry Andric         Offsets.push_back(Dynamic->d_un.d_val);
9450b57cec5SDimitry Andric       }
9460b57cec5SDimitry Andric     }
9470b57cec5SDimitry Andric   }
9480b57cec5SDimitry Andric   for (const Elf_Shdr &Sec : *SectionsOrErr) {
9490b57cec5SDimitry Andric     if (is_contained(Offsets, Sec.sh_addr))
9500b57cec5SDimitry Andric       Res.emplace_back(toDRI(&Sec), this);
9510b57cec5SDimitry Andric   }
9520b57cec5SDimitry Andric   return Res;
9530b57cec5SDimitry Andric }
9540b57cec5SDimitry Andric 
9550b57cec5SDimitry Andric template <class ELFT>
isSectionVirtual(DataRefImpl Sec)9560b57cec5SDimitry Andric bool ELFObjectFile<ELFT>::isSectionVirtual(DataRefImpl Sec) const {
9570b57cec5SDimitry Andric   return getSection(Sec)->sh_type == ELF::SHT_NOBITS;
9580b57cec5SDimitry Andric }
9590b57cec5SDimitry Andric 
9600b57cec5SDimitry Andric template <class ELFT>
isBerkeleyText(DataRefImpl Sec)9610b57cec5SDimitry Andric bool ELFObjectFile<ELFT>::isBerkeleyText(DataRefImpl Sec) const {
9620b57cec5SDimitry Andric   return getSection(Sec)->sh_flags & ELF::SHF_ALLOC &&
9630b57cec5SDimitry Andric          (getSection(Sec)->sh_flags & ELF::SHF_EXECINSTR ||
9640b57cec5SDimitry Andric           !(getSection(Sec)->sh_flags & ELF::SHF_WRITE));
9650b57cec5SDimitry Andric }
9660b57cec5SDimitry Andric 
9670b57cec5SDimitry Andric template <class ELFT>
isBerkeleyData(DataRefImpl Sec)9680b57cec5SDimitry Andric bool ELFObjectFile<ELFT>::isBerkeleyData(DataRefImpl Sec) const {
9690b57cec5SDimitry Andric   const Elf_Shdr *EShdr = getSection(Sec);
9700b57cec5SDimitry Andric   return !isBerkeleyText(Sec) && EShdr->sh_type != ELF::SHT_NOBITS &&
9710b57cec5SDimitry Andric          EShdr->sh_flags & ELF::SHF_ALLOC;
9720b57cec5SDimitry Andric }
9730b57cec5SDimitry Andric 
9740b57cec5SDimitry Andric template <class ELFT>
isDebugSection(DataRefImpl Sec)975fe6060f1SDimitry Andric bool ELFObjectFile<ELFT>::isDebugSection(DataRefImpl Sec) const {
976fe6060f1SDimitry Andric   Expected<StringRef> SectionNameOrErr = getSectionName(Sec);
977fe6060f1SDimitry Andric   if (!SectionNameOrErr) {
978fe6060f1SDimitry Andric     // TODO: Report the error message properly.
979fe6060f1SDimitry Andric     consumeError(SectionNameOrErr.takeError());
980fe6060f1SDimitry Andric     return false;
981fe6060f1SDimitry Andric   }
982fe6060f1SDimitry Andric   StringRef SectionName = SectionNameOrErr.get();
9835f757f3fSDimitry Andric   return SectionName.starts_with(".debug") ||
9845f757f3fSDimitry Andric          SectionName.starts_with(".zdebug") || SectionName == ".gdb_index";
9855ffd83dbSDimitry Andric }
9865ffd83dbSDimitry Andric 
9875ffd83dbSDimitry Andric template <class ELFT>
9880b57cec5SDimitry Andric relocation_iterator
section_rel_begin(DataRefImpl Sec)9890b57cec5SDimitry Andric ELFObjectFile<ELFT>::section_rel_begin(DataRefImpl Sec) const {
9900b57cec5SDimitry Andric   DataRefImpl RelData;
9910b57cec5SDimitry Andric   auto SectionsOrErr = EF.sections();
9920b57cec5SDimitry Andric   if (!SectionsOrErr)
9930b57cec5SDimitry Andric     return relocation_iterator(RelocationRef());
9940b57cec5SDimitry Andric   uintptr_t SHT = reinterpret_cast<uintptr_t>((*SectionsOrErr).begin());
995e8d8bef9SDimitry Andric   RelData.d.a = (Sec.p - SHT) / EF.getHeader().e_shentsize;
9960b57cec5SDimitry Andric   RelData.d.b = 0;
9970b57cec5SDimitry Andric   return relocation_iterator(RelocationRef(RelData, this));
9980b57cec5SDimitry Andric }
9990b57cec5SDimitry Andric 
10000b57cec5SDimitry Andric template <class ELFT>
10010b57cec5SDimitry Andric relocation_iterator
section_rel_end(DataRefImpl Sec)10020b57cec5SDimitry Andric ELFObjectFile<ELFT>::section_rel_end(DataRefImpl Sec) const {
10030b57cec5SDimitry Andric   const Elf_Shdr *S = reinterpret_cast<const Elf_Shdr *>(Sec.p);
10040b57cec5SDimitry Andric   relocation_iterator Begin = section_rel_begin(Sec);
10050b57cec5SDimitry Andric   if (S->sh_type != ELF::SHT_RELA && S->sh_type != ELF::SHT_REL)
10060b57cec5SDimitry Andric     return Begin;
10070b57cec5SDimitry Andric   DataRefImpl RelData = Begin->getRawDataRefImpl();
10080b57cec5SDimitry Andric   const Elf_Shdr *RelSec = getRelSection(RelData);
10090b57cec5SDimitry Andric 
10100b57cec5SDimitry Andric   // Error check sh_link here so that getRelocationSymbol can just use it.
10110b57cec5SDimitry Andric   auto SymSecOrErr = EF.getSection(RelSec->sh_link);
10120b57cec5SDimitry Andric   if (!SymSecOrErr)
1013349cc55cSDimitry Andric     report_fatal_error(
1014349cc55cSDimitry Andric         Twine(errorToErrorCode(SymSecOrErr.takeError()).message()));
10150b57cec5SDimitry Andric 
10160b57cec5SDimitry Andric   RelData.d.b += S->sh_size / S->sh_entsize;
10170b57cec5SDimitry Andric   return relocation_iterator(RelocationRef(RelData, this));
10180b57cec5SDimitry Andric }
10190b57cec5SDimitry Andric 
10200b57cec5SDimitry Andric template <class ELFT>
10218bcb0991SDimitry Andric Expected<section_iterator>
getRelocatedSection(DataRefImpl Sec)10220b57cec5SDimitry Andric ELFObjectFile<ELFT>::getRelocatedSection(DataRefImpl Sec) const {
10230b57cec5SDimitry Andric   const Elf_Shdr *EShdr = getSection(Sec);
10240b57cec5SDimitry Andric   uintX_t Type = EShdr->sh_type;
10250b57cec5SDimitry Andric   if (Type != ELF::SHT_REL && Type != ELF::SHT_RELA)
10260b57cec5SDimitry Andric     return section_end();
10270b57cec5SDimitry Andric 
10288bcb0991SDimitry Andric   Expected<const Elf_Shdr *> SecOrErr = EF.getSection(EShdr->sh_info);
10298bcb0991SDimitry Andric   if (!SecOrErr)
10308bcb0991SDimitry Andric     return SecOrErr.takeError();
10318bcb0991SDimitry Andric   return section_iterator(SectionRef(toDRI(*SecOrErr), this));
10320b57cec5SDimitry Andric }
10330b57cec5SDimitry Andric 
10340b57cec5SDimitry Andric // Relocations
10350b57cec5SDimitry Andric template <class ELFT>
moveRelocationNext(DataRefImpl & Rel)10360b57cec5SDimitry Andric void ELFObjectFile<ELFT>::moveRelocationNext(DataRefImpl &Rel) const {
10370b57cec5SDimitry Andric   ++Rel.d.b;
10380b57cec5SDimitry Andric }
10390b57cec5SDimitry Andric 
10400b57cec5SDimitry Andric template <class ELFT>
10410b57cec5SDimitry Andric symbol_iterator
getRelocationSymbol(DataRefImpl Rel)10420b57cec5SDimitry Andric ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel) const {
10430b57cec5SDimitry Andric   uint32_t symbolIdx;
10440b57cec5SDimitry Andric   const Elf_Shdr *sec = getRelSection(Rel);
10450b57cec5SDimitry Andric   if (sec->sh_type == ELF::SHT_REL)
10460b57cec5SDimitry Andric     symbolIdx = getRel(Rel)->getSymbol(EF.isMips64EL());
10470b57cec5SDimitry Andric   else
10480b57cec5SDimitry Andric     symbolIdx = getRela(Rel)->getSymbol(EF.isMips64EL());
10490b57cec5SDimitry Andric   if (!symbolIdx)
10500b57cec5SDimitry Andric     return symbol_end();
10510b57cec5SDimitry Andric 
10520b57cec5SDimitry Andric   // FIXME: error check symbolIdx
10530b57cec5SDimitry Andric   DataRefImpl SymbolData;
10540b57cec5SDimitry Andric   SymbolData.d.a = sec->sh_link;
10550b57cec5SDimitry Andric   SymbolData.d.b = symbolIdx;
10560b57cec5SDimitry Andric   return symbol_iterator(SymbolRef(SymbolData, this));
10570b57cec5SDimitry Andric }
10580b57cec5SDimitry Andric 
10590b57cec5SDimitry Andric template <class ELFT>
getRelocationOffset(DataRefImpl Rel)10600b57cec5SDimitry Andric uint64_t ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel) const {
10610b57cec5SDimitry Andric   const Elf_Shdr *sec = getRelSection(Rel);
10620b57cec5SDimitry Andric   if (sec->sh_type == ELF::SHT_REL)
10630b57cec5SDimitry Andric     return getRel(Rel)->r_offset;
10640b57cec5SDimitry Andric 
10650b57cec5SDimitry Andric   return getRela(Rel)->r_offset;
10660b57cec5SDimitry Andric }
10670b57cec5SDimitry Andric 
10680b57cec5SDimitry Andric template <class ELFT>
getRelocationType(DataRefImpl Rel)10690b57cec5SDimitry Andric uint64_t ELFObjectFile<ELFT>::getRelocationType(DataRefImpl Rel) const {
10700b57cec5SDimitry Andric   const Elf_Shdr *sec = getRelSection(Rel);
10710b57cec5SDimitry Andric   if (sec->sh_type == ELF::SHT_REL)
10720b57cec5SDimitry Andric     return getRel(Rel)->getType(EF.isMips64EL());
10730b57cec5SDimitry Andric   else
10740b57cec5SDimitry Andric     return getRela(Rel)->getType(EF.isMips64EL());
10750b57cec5SDimitry Andric }
10760b57cec5SDimitry Andric 
10770b57cec5SDimitry Andric template <class ELFT>
getRelocationTypeName(uint32_t Type)10780b57cec5SDimitry Andric StringRef ELFObjectFile<ELFT>::getRelocationTypeName(uint32_t Type) const {
1079e8d8bef9SDimitry Andric   return getELFRelocationTypeName(EF.getHeader().e_machine, Type);
10800b57cec5SDimitry Andric }
10810b57cec5SDimitry Andric 
10820b57cec5SDimitry Andric template <class ELFT>
getRelocationTypeName(DataRefImpl Rel,SmallVectorImpl<char> & Result)10830b57cec5SDimitry Andric void ELFObjectFile<ELFT>::getRelocationTypeName(
10840b57cec5SDimitry Andric     DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
10850b57cec5SDimitry Andric   uint32_t type = getRelocationType(Rel);
10860b57cec5SDimitry Andric   EF.getRelocationTypeName(type, Result);
10870b57cec5SDimitry Andric }
10880b57cec5SDimitry Andric 
10890b57cec5SDimitry Andric template <class ELFT>
10900b57cec5SDimitry Andric Expected<int64_t>
getRelocationAddend(DataRefImpl Rel)10910b57cec5SDimitry Andric ELFObjectFile<ELFT>::getRelocationAddend(DataRefImpl Rel) const {
10920b57cec5SDimitry Andric   if (getRelSection(Rel)->sh_type != ELF::SHT_RELA)
10930b57cec5SDimitry Andric     return createError("Section is not SHT_RELA");
10940b57cec5SDimitry Andric   return (int64_t)getRela(Rel)->r_addend;
10950b57cec5SDimitry Andric }
10960b57cec5SDimitry Andric 
10970b57cec5SDimitry Andric template <class ELFT>
10980b57cec5SDimitry Andric const typename ELFObjectFile<ELFT>::Elf_Rel *
getRel(DataRefImpl Rel)10990b57cec5SDimitry Andric ELFObjectFile<ELFT>::getRel(DataRefImpl Rel) const {
11000b57cec5SDimitry Andric   assert(getRelSection(Rel)->sh_type == ELF::SHT_REL);
11010b57cec5SDimitry Andric   auto Ret = EF.template getEntry<Elf_Rel>(Rel.d.a, Rel.d.b);
11020b57cec5SDimitry Andric   if (!Ret)
1103349cc55cSDimitry Andric     report_fatal_error(Twine(errorToErrorCode(Ret.takeError()).message()));
11040b57cec5SDimitry Andric   return *Ret;
11050b57cec5SDimitry Andric }
11060b57cec5SDimitry Andric 
11070b57cec5SDimitry Andric template <class ELFT>
11080b57cec5SDimitry Andric const typename ELFObjectFile<ELFT>::Elf_Rela *
getRela(DataRefImpl Rela)11090b57cec5SDimitry Andric ELFObjectFile<ELFT>::getRela(DataRefImpl Rela) const {
11100b57cec5SDimitry Andric   assert(getRelSection(Rela)->sh_type == ELF::SHT_RELA);
11110b57cec5SDimitry Andric   auto Ret = EF.template getEntry<Elf_Rela>(Rela.d.a, Rela.d.b);
11120b57cec5SDimitry Andric   if (!Ret)
1113349cc55cSDimitry Andric     report_fatal_error(Twine(errorToErrorCode(Ret.takeError()).message()));
11140b57cec5SDimitry Andric   return *Ret;
11150b57cec5SDimitry Andric }
11160b57cec5SDimitry Andric 
11170b57cec5SDimitry Andric template <class ELFT>
11180b57cec5SDimitry Andric Expected<ELFObjectFile<ELFT>>
create(MemoryBufferRef Object,bool InitContent)1119e8d8bef9SDimitry Andric ELFObjectFile<ELFT>::create(MemoryBufferRef Object, bool InitContent) {
11200b57cec5SDimitry Andric   auto EFOrErr = ELFFile<ELFT>::create(Object.getBuffer());
11210b57cec5SDimitry Andric   if (Error E = EFOrErr.takeError())
11220b57cec5SDimitry Andric     return std::move(E);
11230b57cec5SDimitry Andric 
1124e8d8bef9SDimitry Andric   ELFObjectFile<ELFT> Obj = {Object, std::move(*EFOrErr), nullptr, nullptr,
1125e8d8bef9SDimitry Andric                              nullptr};
1126e8d8bef9SDimitry Andric   if (InitContent)
1127e8d8bef9SDimitry Andric     if (Error E = Obj.initContent())
1128e8d8bef9SDimitry Andric       return std::move(E);
1129e8d8bef9SDimitry Andric   return std::move(Obj);
11300b57cec5SDimitry Andric }
11310b57cec5SDimitry Andric 
11320b57cec5SDimitry Andric template <class ELFT>
ELFObjectFile(MemoryBufferRef Object,ELFFile<ELFT> EF,const Elf_Shdr * DotDynSymSec,const Elf_Shdr * DotSymtabSec,const Elf_Shdr * DotSymtabShndx)11330b57cec5SDimitry Andric ELFObjectFile<ELFT>::ELFObjectFile(MemoryBufferRef Object, ELFFile<ELFT> EF,
11340b57cec5SDimitry Andric                                    const Elf_Shdr *DotDynSymSec,
11350b57cec5SDimitry Andric                                    const Elf_Shdr *DotSymtabSec,
1136e8d8bef9SDimitry Andric                                    const Elf_Shdr *DotSymtabShndx)
11370b57cec5SDimitry Andric     : ELFObjectFileBase(
11385f757f3fSDimitry Andric           getELFType(ELFT::TargetEndianness == llvm::endianness::little,
11395f757f3fSDimitry Andric                      ELFT::Is64Bits),
11400b57cec5SDimitry Andric           Object),
11410b57cec5SDimitry Andric       EF(EF), DotDynSymSec(DotDynSymSec), DotSymtabSec(DotSymtabSec),
1142e8d8bef9SDimitry Andric       DotSymtabShndxSec(DotSymtabShndx) {}
11430b57cec5SDimitry Andric 
11440b57cec5SDimitry Andric template <class ELFT>
ELFObjectFile(ELFObjectFile<ELFT> && Other)11450b57cec5SDimitry Andric ELFObjectFile<ELFT>::ELFObjectFile(ELFObjectFile<ELFT> &&Other)
11460b57cec5SDimitry Andric     : ELFObjectFile(Other.Data, Other.EF, Other.DotDynSymSec,
1147e8d8bef9SDimitry Andric                     Other.DotSymtabSec, Other.DotSymtabShndxSec) {}
11480b57cec5SDimitry Andric 
11490b57cec5SDimitry Andric template <class ELFT>
symbol_begin()11500b57cec5SDimitry Andric basic_symbol_iterator ELFObjectFile<ELFT>::symbol_begin() const {
11510b57cec5SDimitry Andric   DataRefImpl Sym =
11520b57cec5SDimitry Andric       toDRI(DotSymtabSec,
11530b57cec5SDimitry Andric             DotSymtabSec && DotSymtabSec->sh_size >= sizeof(Elf_Sym) ? 1 : 0);
11540b57cec5SDimitry Andric   return basic_symbol_iterator(SymbolRef(Sym, this));
11550b57cec5SDimitry Andric }
11560b57cec5SDimitry Andric 
11570b57cec5SDimitry Andric template <class ELFT>
symbol_end()11580b57cec5SDimitry Andric basic_symbol_iterator ELFObjectFile<ELFT>::symbol_end() const {
11590b57cec5SDimitry Andric   const Elf_Shdr *SymTab = DotSymtabSec;
11600b57cec5SDimitry Andric   if (!SymTab)
11610b57cec5SDimitry Andric     return symbol_begin();
11620b57cec5SDimitry Andric   DataRefImpl Sym = toDRI(SymTab, SymTab->sh_size / sizeof(Elf_Sym));
11630b57cec5SDimitry Andric   return basic_symbol_iterator(SymbolRef(Sym, this));
11640b57cec5SDimitry Andric }
11650b57cec5SDimitry Andric 
11660b57cec5SDimitry Andric template <class ELFT>
dynamic_symbol_begin()11670b57cec5SDimitry Andric elf_symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_begin() const {
11685ffd83dbSDimitry Andric   if (!DotDynSymSec || DotDynSymSec->sh_size < sizeof(Elf_Sym))
11695ffd83dbSDimitry Andric     // Ignore errors here where the dynsym is empty or sh_size less than the
11705ffd83dbSDimitry Andric     // size of one symbol. These should be handled elsewhere.
11715ffd83dbSDimitry Andric     return symbol_iterator(SymbolRef(toDRI(DotDynSymSec, 0), this));
11725ffd83dbSDimitry Andric   // Skip 0-index NULL symbol.
11735ffd83dbSDimitry Andric   return symbol_iterator(SymbolRef(toDRI(DotDynSymSec, 1), this));
11740b57cec5SDimitry Andric }
11750b57cec5SDimitry Andric 
11760b57cec5SDimitry Andric template <class ELFT>
dynamic_symbol_end()11770b57cec5SDimitry Andric elf_symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_end() const {
11780b57cec5SDimitry Andric   const Elf_Shdr *SymTab = DotDynSymSec;
11790b57cec5SDimitry Andric   if (!SymTab)
11800b57cec5SDimitry Andric     return dynamic_symbol_begin();
11810b57cec5SDimitry Andric   DataRefImpl Sym = toDRI(SymTab, SymTab->sh_size / sizeof(Elf_Sym));
11820b57cec5SDimitry Andric   return basic_symbol_iterator(SymbolRef(Sym, this));
11830b57cec5SDimitry Andric }
11840b57cec5SDimitry Andric 
11850b57cec5SDimitry Andric template <class ELFT>
section_begin()11860b57cec5SDimitry Andric section_iterator ELFObjectFile<ELFT>::section_begin() const {
11870b57cec5SDimitry Andric   auto SectionsOrErr = EF.sections();
11880b57cec5SDimitry Andric   if (!SectionsOrErr)
11890b57cec5SDimitry Andric     return section_iterator(SectionRef());
11900b57cec5SDimitry Andric   return section_iterator(SectionRef(toDRI((*SectionsOrErr).begin()), this));
11910b57cec5SDimitry Andric }
11920b57cec5SDimitry Andric 
11930b57cec5SDimitry Andric template <class ELFT>
section_end()11940b57cec5SDimitry Andric section_iterator ELFObjectFile<ELFT>::section_end() const {
11950b57cec5SDimitry Andric   auto SectionsOrErr = EF.sections();
11960b57cec5SDimitry Andric   if (!SectionsOrErr)
11970b57cec5SDimitry Andric     return section_iterator(SectionRef());
11980b57cec5SDimitry Andric   return section_iterator(SectionRef(toDRI((*SectionsOrErr).end()), this));
11990b57cec5SDimitry Andric }
12000b57cec5SDimitry Andric 
12010b57cec5SDimitry Andric template <class ELFT>
getBytesInAddress()12020b57cec5SDimitry Andric uint8_t ELFObjectFile<ELFT>::getBytesInAddress() const {
12030b57cec5SDimitry Andric   return ELFT::Is64Bits ? 8 : 4;
12040b57cec5SDimitry Andric }
12050b57cec5SDimitry Andric 
12060b57cec5SDimitry Andric template <class ELFT>
getFileFormatName()12070b57cec5SDimitry Andric StringRef ELFObjectFile<ELFT>::getFileFormatName() const {
12085f757f3fSDimitry Andric   constexpr bool IsLittleEndian =
12095f757f3fSDimitry Andric       ELFT::TargetEndianness == llvm::endianness::little;
1210e8d8bef9SDimitry Andric   switch (EF.getHeader().e_ident[ELF::EI_CLASS]) {
12110b57cec5SDimitry Andric   case ELF::ELFCLASS32:
1212e8d8bef9SDimitry Andric     switch (EF.getHeader().e_machine) {
1213fe6060f1SDimitry Andric     case ELF::EM_68K:
1214fe6060f1SDimitry Andric       return "elf32-m68k";
12150b57cec5SDimitry Andric     case ELF::EM_386:
12165ffd83dbSDimitry Andric       return "elf32-i386";
12170b57cec5SDimitry Andric     case ELF::EM_IAMCU:
12185ffd83dbSDimitry Andric       return "elf32-iamcu";
12190b57cec5SDimitry Andric     case ELF::EM_X86_64:
12205ffd83dbSDimitry Andric       return "elf32-x86-64";
12210b57cec5SDimitry Andric     case ELF::EM_ARM:
12225ffd83dbSDimitry Andric       return (IsLittleEndian ? "elf32-littlearm" : "elf32-bigarm");
12230b57cec5SDimitry Andric     case ELF::EM_AVR:
12245ffd83dbSDimitry Andric       return "elf32-avr";
12250b57cec5SDimitry Andric     case ELF::EM_HEXAGON:
12265ffd83dbSDimitry Andric       return "elf32-hexagon";
12270b57cec5SDimitry Andric     case ELF::EM_LANAI:
12285ffd83dbSDimitry Andric       return "elf32-lanai";
12290b57cec5SDimitry Andric     case ELF::EM_MIPS:
12305ffd83dbSDimitry Andric       return "elf32-mips";
12310b57cec5SDimitry Andric     case ELF::EM_MSP430:
12325ffd83dbSDimitry Andric       return "elf32-msp430";
12330b57cec5SDimitry Andric     case ELF::EM_PPC:
1234e8d8bef9SDimitry Andric       return (IsLittleEndian ? "elf32-powerpcle" : "elf32-powerpc");
12350b57cec5SDimitry Andric     case ELF::EM_RISCV:
12365ffd83dbSDimitry Andric       return "elf32-littleriscv";
1237e8d8bef9SDimitry Andric     case ELF::EM_CSKY:
1238e8d8bef9SDimitry Andric       return "elf32-csky";
12390b57cec5SDimitry Andric     case ELF::EM_SPARC:
12400b57cec5SDimitry Andric     case ELF::EM_SPARC32PLUS:
12415ffd83dbSDimitry Andric       return "elf32-sparc";
12420b57cec5SDimitry Andric     case ELF::EM_AMDGPU:
12435ffd83dbSDimitry Andric       return "elf32-amdgpu";
124481ad6265SDimitry Andric     case ELF::EM_LOONGARCH:
124581ad6265SDimitry Andric       return "elf32-loongarch";
1246bdd1243dSDimitry Andric     case ELF::EM_XTENSA:
1247bdd1243dSDimitry Andric       return "elf32-xtensa";
12480b57cec5SDimitry Andric     default:
12495ffd83dbSDimitry Andric       return "elf32-unknown";
12500b57cec5SDimitry Andric     }
12510b57cec5SDimitry Andric   case ELF::ELFCLASS64:
1252e8d8bef9SDimitry Andric     switch (EF.getHeader().e_machine) {
12530b57cec5SDimitry Andric     case ELF::EM_386:
12545ffd83dbSDimitry Andric       return "elf64-i386";
12550b57cec5SDimitry Andric     case ELF::EM_X86_64:
12565ffd83dbSDimitry Andric       return "elf64-x86-64";
12570b57cec5SDimitry Andric     case ELF::EM_AARCH64:
12585ffd83dbSDimitry Andric       return (IsLittleEndian ? "elf64-littleaarch64" : "elf64-bigaarch64");
12590b57cec5SDimitry Andric     case ELF::EM_PPC64:
12605ffd83dbSDimitry Andric       return (IsLittleEndian ? "elf64-powerpcle" : "elf64-powerpc");
12610b57cec5SDimitry Andric     case ELF::EM_RISCV:
12625ffd83dbSDimitry Andric       return "elf64-littleriscv";
12630b57cec5SDimitry Andric     case ELF::EM_S390:
12645ffd83dbSDimitry Andric       return "elf64-s390";
12650b57cec5SDimitry Andric     case ELF::EM_SPARCV9:
12665ffd83dbSDimitry Andric       return "elf64-sparc";
12670b57cec5SDimitry Andric     case ELF::EM_MIPS:
12685ffd83dbSDimitry Andric       return "elf64-mips";
12690b57cec5SDimitry Andric     case ELF::EM_AMDGPU:
12705ffd83dbSDimitry Andric       return "elf64-amdgpu";
12710b57cec5SDimitry Andric     case ELF::EM_BPF:
12725ffd83dbSDimitry Andric       return "elf64-bpf";
12735ffd83dbSDimitry Andric     case ELF::EM_VE:
12745ffd83dbSDimitry Andric       return "elf64-ve";
127581ad6265SDimitry Andric     case ELF::EM_LOONGARCH:
127681ad6265SDimitry Andric       return "elf64-loongarch";
12770b57cec5SDimitry Andric     default:
12785ffd83dbSDimitry Andric       return "elf64-unknown";
12790b57cec5SDimitry Andric     }
12800b57cec5SDimitry Andric   default:
12810b57cec5SDimitry Andric     // FIXME: Proper error handling.
12820b57cec5SDimitry Andric     report_fatal_error("Invalid ELFCLASS!");
12830b57cec5SDimitry Andric   }
12840b57cec5SDimitry Andric }
12850b57cec5SDimitry Andric 
getArch()12860b57cec5SDimitry Andric template <class ELFT> Triple::ArchType ELFObjectFile<ELFT>::getArch() const {
12875f757f3fSDimitry Andric   bool IsLittleEndian = ELFT::TargetEndianness == llvm::endianness::little;
1288e8d8bef9SDimitry Andric   switch (EF.getHeader().e_machine) {
1289fe6060f1SDimitry Andric   case ELF::EM_68K:
1290fe6060f1SDimitry Andric     return Triple::m68k;
12910b57cec5SDimitry Andric   case ELF::EM_386:
12920b57cec5SDimitry Andric   case ELF::EM_IAMCU:
12930b57cec5SDimitry Andric     return Triple::x86;
12940b57cec5SDimitry Andric   case ELF::EM_X86_64:
12950b57cec5SDimitry Andric     return Triple::x86_64;
12960b57cec5SDimitry Andric   case ELF::EM_AARCH64:
12970b57cec5SDimitry Andric     return IsLittleEndian ? Triple::aarch64 : Triple::aarch64_be;
12980b57cec5SDimitry Andric   case ELF::EM_ARM:
12990b57cec5SDimitry Andric     return Triple::arm;
13000b57cec5SDimitry Andric   case ELF::EM_AVR:
13010b57cec5SDimitry Andric     return Triple::avr;
13020b57cec5SDimitry Andric   case ELF::EM_HEXAGON:
13030b57cec5SDimitry Andric     return Triple::hexagon;
13040b57cec5SDimitry Andric   case ELF::EM_LANAI:
13050b57cec5SDimitry Andric     return Triple::lanai;
13060b57cec5SDimitry Andric   case ELF::EM_MIPS:
1307e8d8bef9SDimitry Andric     switch (EF.getHeader().e_ident[ELF::EI_CLASS]) {
13080b57cec5SDimitry Andric     case ELF::ELFCLASS32:
13090b57cec5SDimitry Andric       return IsLittleEndian ? Triple::mipsel : Triple::mips;
13100b57cec5SDimitry Andric     case ELF::ELFCLASS64:
13110b57cec5SDimitry Andric       return IsLittleEndian ? Triple::mips64el : Triple::mips64;
13120b57cec5SDimitry Andric     default:
13130b57cec5SDimitry Andric       report_fatal_error("Invalid ELFCLASS!");
13140b57cec5SDimitry Andric     }
13150b57cec5SDimitry Andric   case ELF::EM_MSP430:
13160b57cec5SDimitry Andric     return Triple::msp430;
13170b57cec5SDimitry Andric   case ELF::EM_PPC:
1318e8d8bef9SDimitry Andric     return IsLittleEndian ? Triple::ppcle : Triple::ppc;
13190b57cec5SDimitry Andric   case ELF::EM_PPC64:
13200b57cec5SDimitry Andric     return IsLittleEndian ? Triple::ppc64le : Triple::ppc64;
13210b57cec5SDimitry Andric   case ELF::EM_RISCV:
1322e8d8bef9SDimitry Andric     switch (EF.getHeader().e_ident[ELF::EI_CLASS]) {
13230b57cec5SDimitry Andric     case ELF::ELFCLASS32:
13240b57cec5SDimitry Andric       return Triple::riscv32;
13250b57cec5SDimitry Andric     case ELF::ELFCLASS64:
13260b57cec5SDimitry Andric       return Triple::riscv64;
13270b57cec5SDimitry Andric     default:
13280b57cec5SDimitry Andric       report_fatal_error("Invalid ELFCLASS!");
13290b57cec5SDimitry Andric     }
13300b57cec5SDimitry Andric   case ELF::EM_S390:
13310b57cec5SDimitry Andric     return Triple::systemz;
13320b57cec5SDimitry Andric 
13330b57cec5SDimitry Andric   case ELF::EM_SPARC:
13340b57cec5SDimitry Andric   case ELF::EM_SPARC32PLUS:
13350b57cec5SDimitry Andric     return IsLittleEndian ? Triple::sparcel : Triple::sparc;
13360b57cec5SDimitry Andric   case ELF::EM_SPARCV9:
13370b57cec5SDimitry Andric     return Triple::sparcv9;
13380b57cec5SDimitry Andric 
13390b57cec5SDimitry Andric   case ELF::EM_AMDGPU: {
13400b57cec5SDimitry Andric     if (!IsLittleEndian)
13410b57cec5SDimitry Andric       return Triple::UnknownArch;
13420b57cec5SDimitry Andric 
1343e8d8bef9SDimitry Andric     unsigned MACH = EF.getHeader().e_flags & ELF::EF_AMDGPU_MACH;
13440b57cec5SDimitry Andric     if (MACH >= ELF::EF_AMDGPU_MACH_R600_FIRST &&
13450b57cec5SDimitry Andric         MACH <= ELF::EF_AMDGPU_MACH_R600_LAST)
13460b57cec5SDimitry Andric       return Triple::r600;
13470b57cec5SDimitry Andric     if (MACH >= ELF::EF_AMDGPU_MACH_AMDGCN_FIRST &&
13480b57cec5SDimitry Andric         MACH <= ELF::EF_AMDGPU_MACH_AMDGCN_LAST)
13490b57cec5SDimitry Andric       return Triple::amdgcn;
13500b57cec5SDimitry Andric 
13510b57cec5SDimitry Andric     return Triple::UnknownArch;
13520b57cec5SDimitry Andric   }
13530b57cec5SDimitry Andric 
13541db9f3b2SDimitry Andric   case ELF::EM_CUDA: {
13551db9f3b2SDimitry Andric     if (EF.getHeader().e_ident[ELF::EI_CLASS] == ELF::ELFCLASS32)
13561db9f3b2SDimitry Andric       return Triple::nvptx;
13571db9f3b2SDimitry Andric     return Triple::nvptx64;
13581db9f3b2SDimitry Andric   }
13591db9f3b2SDimitry Andric 
13600b57cec5SDimitry Andric   case ELF::EM_BPF:
13610b57cec5SDimitry Andric     return IsLittleEndian ? Triple::bpfel : Triple::bpfeb;
13620b57cec5SDimitry Andric 
13635ffd83dbSDimitry Andric   case ELF::EM_VE:
13645ffd83dbSDimitry Andric     return Triple::ve;
1365e8d8bef9SDimitry Andric   case ELF::EM_CSKY:
1366e8d8bef9SDimitry Andric     return Triple::csky;
136781ad6265SDimitry Andric 
136881ad6265SDimitry Andric   case ELF::EM_LOONGARCH:
136981ad6265SDimitry Andric     switch (EF.getHeader().e_ident[ELF::EI_CLASS]) {
137081ad6265SDimitry Andric     case ELF::ELFCLASS32:
137181ad6265SDimitry Andric       return Triple::loongarch32;
137281ad6265SDimitry Andric     case ELF::ELFCLASS64:
137381ad6265SDimitry Andric       return Triple::loongarch64;
137481ad6265SDimitry Andric     default:
137581ad6265SDimitry Andric       report_fatal_error("Invalid ELFCLASS!");
137681ad6265SDimitry Andric     }
137781ad6265SDimitry Andric 
1378bdd1243dSDimitry Andric   case ELF::EM_XTENSA:
1379bdd1243dSDimitry Andric     return Triple::xtensa;
1380bdd1243dSDimitry Andric 
13810b57cec5SDimitry Andric   default:
13820b57cec5SDimitry Andric     return Triple::UnknownArch;
13830b57cec5SDimitry Andric   }
13840b57cec5SDimitry Andric }
13850b57cec5SDimitry Andric 
getOS()13861db9f3b2SDimitry Andric template <class ELFT> Triple::OSType ELFObjectFile<ELFT>::getOS() const {
13871db9f3b2SDimitry Andric   switch (EF.getHeader().e_ident[ELF::EI_OSABI]) {
13881db9f3b2SDimitry Andric   case ELF::ELFOSABI_NETBSD:
13891db9f3b2SDimitry Andric     return Triple::NetBSD;
13901db9f3b2SDimitry Andric   case ELF::ELFOSABI_LINUX:
13911db9f3b2SDimitry Andric     return Triple::Linux;
13921db9f3b2SDimitry Andric   case ELF::ELFOSABI_HURD:
13931db9f3b2SDimitry Andric     return Triple::Hurd;
13941db9f3b2SDimitry Andric   case ELF::ELFOSABI_SOLARIS:
13951db9f3b2SDimitry Andric     return Triple::Solaris;
13961db9f3b2SDimitry Andric   case ELF::ELFOSABI_AIX:
13971db9f3b2SDimitry Andric     return Triple::AIX;
13981db9f3b2SDimitry Andric   case ELF::ELFOSABI_FREEBSD:
13991db9f3b2SDimitry Andric     return Triple::FreeBSD;
14001db9f3b2SDimitry Andric   case ELF::ELFOSABI_OPENBSD:
14011db9f3b2SDimitry Andric     return Triple::OpenBSD;
14021db9f3b2SDimitry Andric   case ELF::ELFOSABI_CUDA:
14031db9f3b2SDimitry Andric     return Triple::CUDA;
14041db9f3b2SDimitry Andric   case ELF::ELFOSABI_AMDGPU_HSA:
14051db9f3b2SDimitry Andric     return Triple::AMDHSA;
14061db9f3b2SDimitry Andric   case ELF::ELFOSABI_AMDGPU_PAL:
14071db9f3b2SDimitry Andric     return Triple::AMDPAL;
14081db9f3b2SDimitry Andric   case ELF::ELFOSABI_AMDGPU_MESA3D:
14091db9f3b2SDimitry Andric     return Triple::Mesa3D;
14101db9f3b2SDimitry Andric   default:
14111db9f3b2SDimitry Andric     return Triple::UnknownOS;
14121db9f3b2SDimitry Andric   }
14131db9f3b2SDimitry Andric }
14141db9f3b2SDimitry Andric 
14150b57cec5SDimitry Andric template <class ELFT>
getStartAddress()14160b57cec5SDimitry Andric Expected<uint64_t> ELFObjectFile<ELFT>::getStartAddress() const {
1417e8d8bef9SDimitry Andric   return EF.getHeader().e_entry;
14180b57cec5SDimitry Andric }
14190b57cec5SDimitry Andric 
14200b57cec5SDimitry Andric template <class ELFT>
14210b57cec5SDimitry Andric ELFObjectFileBase::elf_symbol_iterator_range
getDynamicSymbolIterators()14220b57cec5SDimitry Andric ELFObjectFile<ELFT>::getDynamicSymbolIterators() const {
14230b57cec5SDimitry Andric   return make_range(dynamic_symbol_begin(), dynamic_symbol_end());
14240b57cec5SDimitry Andric }
14250b57cec5SDimitry Andric 
isRelocatableObject()14260b57cec5SDimitry Andric template <class ELFT> bool ELFObjectFile<ELFT>::isRelocatableObject() const {
1427e8d8bef9SDimitry Andric   return EF.getHeader().e_type == ELF::ET_REL;
14280b57cec5SDimitry Andric }
14290b57cec5SDimitry Andric 
14300b57cec5SDimitry Andric } // end namespace object
14310b57cec5SDimitry Andric } // end namespace llvm
14320b57cec5SDimitry Andric 
14330b57cec5SDimitry Andric #endif // LLVM_OBJECT_ELFOBJECTFILE_H
1434