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