14 #ifndef LLVM_OBJECT_ELFOBJECTFILE_H 15 #define LLVM_OBJECT_ELFOBJECTFILE_H 40 #include <system_error> 45 class elf_symbol_iterator;
88 virtual uint16_t
getEType()
const = 0;
104 return getObject()->getSectionType(getRawDataRefImpl());
108 return getObject()->getSectionFlags(getRawDataRefImpl());
112 return getObject()->getSectionOffset(getRawDataRefImpl());
119 assert(isa<ELFObjectFileBase>(B->getObject()));
142 return getObject()->getSymbolSize(getRawDataRefImpl());
146 return getObject()->getSymbolOther(getRawDataRefImpl());
150 return getObject()->getSymbolELFType(getRawDataRefImpl());
180 return getObject()->getRelocationAddend(getRawDataRefImpl());
284 auto RelSecOrErr = EF.getSection(Rel.d.a);
300 auto SectionsOrErr = EF.sections();
301 if (!SectionsOrErr) {
306 uintptr_t SHT =
reinterpret_cast<uintptr_t
>((*SectionsOrErr).begin());
307 unsigned SymTableIndex =
308 (
reinterpret_cast<uintptr_t
>(SymTable) - SHT) /
sizeof(
Elf_Shdr);
310 DRI.
d.
a = SymTableIndex;
316 return reinterpret_cast<const Elf_Shdr *
>(Sec.
p);
321 DRI.
p =
reinterpret_cast<uintptr_t
>(Sec);
327 DRI.
p =
reinterpret_cast<uintptr_t
>(Dyn);
332 unsigned char Binding = ESym->getBinding();
333 unsigned char Visibility = ESym->getVisibility();
357 auto Ret = EF.template getEntry<Elf_Sym>(Sym.
d.
a, Sym.
d.
b);
364 return reinterpret_cast<const Elf_Shdr *
>(Sec.
p);
386 auto SectionsOrErr = EF.sections();
390 for (
const Elf_Shdr &Sec : *SectionsOrErr) {
392 auto ErrorOrContents = EF.getSectionContents(&Sec);
393 if (!ErrorOrContents)
396 auto Contents = ErrorOrContents.get();
398 return std::error_code();
404 return std::error_code();
425 template <
class ELFT>
430 template <
class ELFT>
433 auto SymTabOrErr = EF.getSection(Sym.
d.
a);
435 return SymTabOrErr.takeError();
436 const Elf_Shdr *SymTableSec = *SymTabOrErr;
437 auto StrTabOrErr = EF.getSection(SymTableSec->sh_link);
439 return StrTabOrErr.takeError();
440 const Elf_Shdr *StringTableSec = *StrTabOrErr;
441 auto SymStrTabOrErr = EF.getStringTable(StringTableSec);
443 return SymStrTabOrErr.takeError();
444 return ESym->getName(*SymStrTabOrErr);
447 template <
class ELFT>
452 template <
class ELFT>
457 template <
class ELFT>
462 template <
class ELFT>
465 uint64_t
Ret = ESym->st_value;
469 const Elf_Ehdr *Header = EF.getHeader();
478 template <
class ELFT>
483 switch (ESym->st_shndx) {
490 const Elf_Ehdr *Header = EF.getHeader();
491 auto SymTabOrErr = EF.getSection(Symb.
d.
a);
493 return SymTabOrErr.takeError();
494 const Elf_Shdr *SymTab = *SymTabOrErr;
497 auto SectionOrErr = EF.getSection(ESym, SymTab, ShndxTable);
499 return SectionOrErr.takeError();
502 Result += Section->sh_addr;
508 template <
class ELFT>
512 return Sym->st_value;
516 template <
class ELFT>
518 return EF.getHeader()->e_machine;
522 return EF.getHeader()->e_type;
525 template <
class ELFT>
530 template <
class ELFT>
535 template <
class ELFT>
540 template <
class ELFT>
545 template <
class ELFT>
550 switch (ESym->getType()) {
568 template <
class ELFT>
586 auto DotSymtabSecSyms = EF.symbols(DotSymtabSec);
587 if (DotSymtabSecSyms && ESym == (*DotSymtabSecSyms).begin())
589 auto DotDynSymSecSyms = EF.symbols(DotDynSymSec);
590 if (DotDynSymSecSyms && ESym == (*DotDynSymSecSyms).begin())
603 if (ESym->getType() ==
ELF::STT_FUNC && (ESym->st_value & 1) == 1)
613 if (isExportedToOtherDSO(ESym))
622 template <
class ELFT>
626 auto ESecOrErr = EF.getSection(ESym, SymTab, ShndxTable);
628 return ESecOrErr.takeError();
635 Sec.
p =
reinterpret_cast<intptr_t>(ESec);
639 template <
class ELFT>
643 auto SymTabOrErr = EF.getSection(Symb.
d.
a);
645 return SymTabOrErr.takeError();
646 const Elf_Shdr *SymTab = *SymTabOrErr;
650 template <
class ELFT>
656 template <
class ELFT>
663 return std::error_code();
666 template <
class ELFT>
671 template <
class ELFT>
673 auto SectionsOrErr = EF.sections();
678 const Elf_Shdr *First = SectionsOrErr->begin();
682 template <
class ELFT>
687 template <
class ELFT>
692 if (std::error_code EC =
694 (uintptr_t)
base() + EShdr->sh_offset, EShdr->sh_size))
696 Result =
StringRef((
const char *)
base() + EShdr->sh_offset, EShdr->sh_size);
697 return std::error_code();
700 template <
class ELFT>
705 template <
class ELFT>
710 template <
class ELFT>
715 template <
class ELFT>
723 template <
class ELFT>
730 template <
class ELFT>
731 std::vector<SectionRef>
733 std::vector<SectionRef> Res;
734 std::vector<uintptr_t>
Offsets;
736 auto SectionsOrErr = EF.sections();
740 for (
const Elf_Shdr &Sec : *SectionsOrErr) {
744 reinterpret_cast<Elf_Dyn *
>((uintptr_t)
base() + Sec.sh_offset);
745 for (; Dynamic->d_tag != ELF::DT_NULL; Dynamic++) {
746 if (Dynamic->d_tag == ELF::DT_REL || Dynamic->d_tag == ELF::DT_RELA ||
747 Dynamic->d_tag == ELF::DT_JMPREL) {
748 Offsets.push_back(Dynamic->d_un.d_val);
752 for (
const Elf_Shdr &Sec : *SectionsOrErr) {
754 Res.emplace_back(toDRI(&Sec),
this);
759 template <
class ELFT>
764 template <
class ELFT>
771 template <
class ELFT>
778 template <
class ELFT>
782 auto SectionsOrErr = EF.sections();
785 uintptr_t SHT =
reinterpret_cast<uintptr_t
>((*SectionsOrErr).begin());
786 RelData.
d.
a = (Sec.
p - SHT) / EF.getHeader()->e_shentsize;
791 template <
class ELFT>
799 const Elf_Shdr *RelSec = getRelSection(RelData);
802 auto SymSecOrErr = EF.getSection(RelSec->sh_link);
806 RelData.
d.
b += S->sh_size / S->sh_entsize;
810 template <
class ELFT>
821 auto R = EF.getSection(EShdr->sh_info);
828 template <
class ELFT>
833 template <
class ELFT>
837 const Elf_Shdr *sec = getRelSection(Rel);
839 symbolIdx = getRel(Rel)->getSymbol(EF.isMips64EL());
841 symbolIdx = getRela(Rel)->getSymbol(EF.isMips64EL());
847 SymbolData.
d.
a = sec->sh_link;
848 SymbolData.
d.
b = symbolIdx;
852 template <
class ELFT>
854 const Elf_Shdr *sec = getRelSection(Rel);
856 return getRel(Rel)->r_offset;
858 return getRela(Rel)->r_offset;
861 template <
class ELFT>
863 const Elf_Shdr *sec = getRelSection(Rel);
865 return getRel(Rel)->getType(EF.isMips64EL());
867 return getRela(Rel)->getType(EF.isMips64EL());
870 template <
class ELFT>
875 template <
class ELFT>
879 EF.getRelocationTypeName(type, Result);
882 template <
class ELFT>
887 return (int64_t)getRela(Rel)->r_addend;
890 template <
class ELFT>
894 auto Ret = EF.template getEntry<Elf_Rel>(Rel.
d.
a, Rel.
d.
b);
900 template <
class ELFT>
904 auto Ret = EF.template getEntry<Elf_Rela>(Rela.
d.
a, Rela.
d.
b);
910 template <
class ELFT>
914 if (
Error E = EFOrErr.takeError())
916 auto EF = std::move(*EFOrErr);
918 auto SectionsOrErr = EF.sections();
920 return SectionsOrErr.takeError();
922 const Elf_Shdr *DotDynSymSec =
nullptr;
923 const Elf_Shdr *DotSymtabSec =
nullptr;
925 for (
const Elf_Shdr &Sec : *SectionsOrErr) {
926 switch (Sec.sh_type) {
929 return createError(
"More than one dynamic symbol table!");
935 return createError(
"More than one static symbol table!");
940 auto TableOrErr = EF.getSHNDXTable(Sec);
942 return TableOrErr.takeError();
943 ShndxTable = *TableOrErr;
952 template <
class ELFT>
960 EF(EF), DotDynSymSec(DotDynSymSec), DotSymtabSec(DotSymtabSec),
961 ShndxTable(ShndxTable) {}
963 template <
class ELFT>
968 template <
class ELFT>
974 template <
class ELFT>
983 template <
class ELFT>
989 template <
class ELFT>
998 template <
class ELFT>
1000 auto SectionsOrErr = EF.
sections();
1006 template <
class ELFT>
1008 auto SectionsOrErr = EF.
sections();
1014 template <
class ELFT>
1016 return ELFT::Is64Bits ? 8 : 4;
1019 template <
class ELFT>
1026 return "ELF32-i386";
1028 return "ELF32-iamcu";
1030 return "ELF32-x86-64";
1032 return (IsLittleEndian ?
"ELF32-arm-little" :
"ELF32-arm-big");
1036 return "ELF32-hexagon";
1038 return "ELF32-lanai";
1040 return "ELF32-mips";
1042 return "ELF32-msp430";
1046 return "ELF32-riscv";
1049 return "ELF32-sparc";
1051 return "ELF32-amdgpu";
1053 return "ELF32-unknown";
1058 return "ELF64-i386";
1060 return "ELF64-x86-64";
1062 return (IsLittleEndian ?
"ELF64-aarch64-little" :
"ELF64-aarch64-big");
1064 return "ELF64-ppc64";
1066 return "ELF64-riscv";
1068 return "ELF64-s390";
1070 return "ELF64-sparc";
1072 return "ELF64-mips";
1074 return "ELF64-amdgpu";
1078 return "ELF64-unknown";
1138 if (!IsLittleEndian)
1160 template <
class ELFT>
1165 template <
class ELFT>
1178 #endif // LLVM_OBJECT_ELFOBJECTFILE_H
const content_type & operator*() const
void getRelocationTypeName(DataRefImpl Rel, SmallVectorImpl< char > &Result) const override
uint64_t getSectionSize(DataRefImpl Sec) const override
virtual uint16_t getEMachine() const =0
static bool classof(const Binary *v)
Expected< uint64_t > getStartAddress() const override
virtual bool isBerkeleyData(DataRefImpl Sec) const
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
This class represents lattice values for constants.
static Expected< ELFFile > create(StringRef Object)
SubtargetFeatures getFeatures() const override
const Elf_Shdr * toELFShdrIter(DataRefImpl Sec) const
std::vector< SectionRef > dynamic_relocation_sections() const override
bool isSectionBSS(DataRefImpl Sec) const override
bool isSectionText(DataRefImpl Sec) const override
elf_relocation_iterator(const relocation_iterator &B)
This provides a very simple, boring adaptor for a begin and end iterator into a range type...
const ELFObjectFileBase * getObject() const
static std::error_code getObject(const T *&Obj, MemoryBufferRef M, const void *Ptr, const uint64_t Size=sizeof(T))
void moveSymbolNext(DataRefImpl &Symb) const override
static std::error_code checkOffset(MemoryBufferRef M, uintptr_t Addr, const uint64_t Size)
bool isRelocatableObject() const override
True if this is a relocatable object (.o/.obj).
Expected< StringRef > getSymbolName(DataRefImpl Symb) const override
virtual bool isSectionBSS(DataRefImpl Sec) const =0
This class is the base class for all object file types.
elf_symbol_iterator_range symbols() const
typename ELFT::Rel Elf_Rel
virtual uint64_t getRelocationOffset(DataRefImpl Rel) const =0
const uint8_t * base() const
ELFYAML::ELF_STV Visibility
virtual std::error_code getSectionName(DataRefImpl Sec, StringRef &Res) const =0
static Error createError(StringRef Err)
const ObjectFile * getObject() const
virtual uint32_t getSymbolAlignment(DataRefImpl Symb) const
Base class for error info classes.
bool isSectionVirtual(DataRefImpl Sec) const override
virtual Expected< StringRef > getSymbolName(DataRefImpl Symb) const =0
uint32_t getSectionType(DataRefImpl Sec) const override
virtual Expected< int64_t > getRelocationAddend(DataRefImpl Rel) const =0
void moveRelocationNext(DataRefImpl &Rel) const override
virtual relocation_iterator section_rel_end(DataRefImpl Sec) const =0
basic_symbol_iterator symbol_begin() const override
symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override
virtual basic_symbol_iterator symbol_begin() const =0
amdgpu Simplify well known AMD library false Value Value const Twine & Name
void setARMSubArch(Triple &TheTriple) const override
uint8_t getSymbolOther(DataRefImpl Symb) const override
const Elf_Shdr * DotSymtabSec
uint64_t getSectionAlignment(DataRefImpl Sec) const override
virtual std::error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const =0
Expected< Elf_Shdr_Range > sections() const
StringRef getBuffer() const
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
This is a value type class that represents a single relocation in the list of relocations in the obje...
Expected< section_iterator > getSymbolSection(const Elf_Sym *Symb, const Elf_Shdr *SymTab) const
elf_section_iterator(const section_iterator &B)
typename ELFT::Ehdr Elf_Ehdr
virtual uint64_t getSectionIndex(DataRefImpl Sec) const =0
const ELFObjectFileBase * getObject() const
Tagged union holding either a T or a Error.
Expected< const typename ELFT::Shdr * > getSection(typename ELFT::ShdrRange Sections, uint32_t Index)
virtual relocation_iterator section_rel_begin(DataRefImpl Sec) const =0
content_iterator< SectionRef > section_iterator
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
uint64_t getSymbolValueImpl(DataRefImpl Symb) const override
const ObjectFile * getObject() const
uint8_t getBytesInAddress() const override
The number of bytes used to represent an address in this object file format.
DataRefImpl toDRI(const Elf_Shdr *SymTable, unsigned SymbolNum) const
virtual uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const =0
section_iterator section_begin() const override
std::error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const override
MemoryBufferRef getMemoryBufferRef() const
void moveSectionNext(DataRefImpl &Sec) const override
elf_symbol_iterator_range getDynamicSymbolIterators() const override
virtual uint64_t getSectionAlignment(DataRefImpl Sec) const =0
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
virtual Expected< uint64_t > getStartAddress() const
DataRefImpl toDRI(const Elf_Dyn *Dyn) const
std::error_code getBuildAttributes(ARMAttributeParser &Attributes) const override
struct llvm::object::DataRefImpl::@282 d
const ObjectFile * getObject() const
virtual uint64_t getSectionOffset(DataRefImpl Sec) const =0
Expected< const typename ELFT::Sym * > getSymbol(typename ELFT::SymRange Symbols, uint32_t Index)
std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type cast(const Y &Val)
elf_symbol_iterator dynamic_symbol_begin() const
relocation_iterator section_rel_end(DataRefImpl Sec) const override
typename ELFT::Shdr Elf_Shdr
Expected< int64_t > getRelocationAddend(DataRefImpl Rel) const override
std::vector< std::pair< DataRefImpl, uint64_t > > getPltAddresses() const
const content_type * operator->() const
unsigned getPlatformFlags() const override
Returns platform-specific object flags, if any.
const Elf_Shdr * getSection(DataRefImpl Sec) const
virtual Expected< SymbolRef::Type > getSymbolType(DataRefImpl Symb) const =0
virtual uint32_t getSymbolFlags(DataRefImpl Symb) const =0
const Elf_Sym * getSymbol(DataRefImpl Sym) const
ELFRelocationRef(const RelocationRef &B)
uint64_t getFlags() const
static bool classof(const Binary *v)
const ELFObjectFileBase * getObject() const
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
const Elf_Rela * getRela(DataRefImpl Rela) const
virtual uint8_t getBytesInAddress() const =0
The number of bytes used to represent an address in this object file format.
virtual void moveRelocationNext(DataRefImpl &Rel) const =0
The instances of the Type class are immutable: once they are created, they are never changed...
unsigned int getType() const
uint32_t getSymbolFlags(DataRefImpl Symb) const override
virtual uint64_t getSectionFlags(DataRefImpl Sec) const =0
iterator_range< elf_symbol_iterator > elf_symbol_iterator_range
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
typename ELFT::Sym Elf_Sym
const Elf_Shdr * DotDynSymSec
Expected< int64_t > getAddend() const
static unsigned int getELFType(bool isLE, bool is64Bits)
section_iterator getRelocatedSection(DataRefImpl Sec) const override
const Elf_Rel * getRel(DataRefImpl Rel) const
virtual std::vector< SectionRef > dynamic_relocation_sections() const
uint32_t getSymbolAlignment(DataRefImpl Symb) const override
bool isSectionData(DataRefImpl Sec) const override
typename ELFT::Dyn Elf_Dyn
virtual basic_symbol_iterator symbol_end() const =0
static Expected< ELFObjectFile< ELFT > > create(MemoryBufferRef Object)
bool isExportedToOtherDSO(const Elf_Sym *ESym) const
uint8_t getSymbolELFType(DataRefImpl Symb) const override
uint64_t getSectionIndex(DataRefImpl Sec) const override
StringRef getFileFormatName() const override
const ELFSymbolRef & operator*() const
void consumeError(Error Err)
Consume a Error without doing anything.
const ELFSectionRef & operator*() const
DataRefImpl toDRI(const Elf_Shdr *Sec) const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const ELFSectionRef * operator->() const
ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source)
Triple - Helper class for working with autoconf configuration names.
uint64_t getSectionAddress(DataRefImpl Sec) const override
std::error_code getSectionName(DataRefImpl Sec, StringRef &Res) const override
uint64_t getRelocationOffset(DataRefImpl Rel) const override
bool isBerkeleyText(DataRefImpl Sec) const override
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type)
typename ELFT::Rela Elf_Rela
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
virtual Expected< uint64_t > getSymbolAddress(DataRefImpl Symb) const =0
uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override
friend class RelocationRef
const ELFFile< ELFT > * getELFFile() const
virtual section_iterator section_begin() const =0
const SymbolicFile * getObject() const
const SymbolRef & operator*() const
virtual uint64_t getSectionAddress(DataRefImpl Sec) const =0
virtual Triple::ArchType getArch() const =0
uint64_t getSymbolValue(DataRefImpl Symb) const
virtual unsigned getPlatformFlags() const =0
Returns platform-specific object flags, if any.
virtual symbol_iterator getRelocationSymbol(DataRefImpl Rel) const =0
uint64_t getSectionFlags(DataRefImpl Sec) const override
Expected< uint64_t > getSymbolAddress(DataRefImpl Symb) const override
Triple::ArchType getArch() const override
content_iterator< BasicSymbolRef > basic_symbol_iterator
elf_symbol_iterator dynamic_symbol_end() const
A range adaptor for a pair of iterators.
Manages the enabling and disabling of subtarget specific features.
bool isBerkeleyData(DataRefImpl Sec) const override
uint64_t getOffset() const
virtual bool isSectionText(DataRefImpl Sec) const =0
virtual uint64_t getSymbolSize(DataRefImpl Symb) const =0
SubtargetFeatures getMIPSFeatures() const
This is a value type class that represents a single symbol in the list of symbols in the object file...
relocation_iterator section_rel_begin(DataRefImpl Sec) const override
Expected< SymbolRef::Type > getSymbolType(DataRefImpl Symb) const override
uint8_t getELFType() const
virtual void moveSectionNext(DataRefImpl &Sec) const =0
virtual section_iterator section_end() const =0
virtual bool isBerkeleyText(DataRefImpl Sec) const
basic_symbol_iterator symbol_end() const override
virtual uint16_t getEType() const =0
bool isSectionCompressed(DataRefImpl Sec) const override
virtual bool isSectionData(DataRefImpl Sec) const =0
ELFSectionRef(const SectionRef &B)
const ELFSymbolRef * operator->() const
uint64_t getSectionOffset(DataRefImpl Sec) const override
virtual section_iterator getRelocatedSection(DataRefImpl Sec) const
virtual uint32_t getSectionType(DataRefImpl Sec) const =0
virtual void moveSymbolNext(DataRefImpl &Symb) const =0
virtual uint64_t getSymbolValueImpl(DataRefImpl Symb) const =0
virtual bool isRelocatableObject() const =0
True if this is a relocatable object (.o/.obj).
section_iterator section_end() const override
const SymbolRef * operator->() const
virtual bool isSectionCompressed(DataRefImpl Sec) const =0
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
virtual Expected< section_iterator > getSymbolSection(DataRefImpl Symb) const =0
virtual elf_symbol_iterator_range getDynamicSymbolIterators() const =0
virtual bool isSectionVirtual(DataRefImpl Sec) const =0
void Parse(ArrayRef< uint8_t > Section, bool isLittle)
virtual uint64_t getSectionSize(DataRefImpl Sec) const =0
Lightweight error class with error context and mandatory checking.
virtual void getRelocationTypeName(DataRefImpl Rel, SmallVectorImpl< char > &Result) const =0
const ELFRelocationRef & operator*() const
content_iterator< RelocationRef > relocation_iterator
SubtargetFeatures getARMFeatures() const
uint64_t getRelocationType(DataRefImpl Rel) const override
#define LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
StringRef - Represent a constant reference to a string, i.e.
virtual uint8_t getSymbolELFType(DataRefImpl Symb) const =0
SubtargetFeatures getRISCVFeatures() const
const Elf_Ehdr * getHeader() const
virtual uint8_t getSymbolOther(DataRefImpl Symb) const =0
const ELFRelocationRef * operator->() const
elf_symbol_iterator(const basic_symbol_iterator &B)
virtual StringRef getFileFormatName() const =0
virtual uint64_t getRelocationType(DataRefImpl Rel) const =0
std::error_code errorToErrorCode(Error Err)
Helper for converting an ECError to a std::error_code.
typename ELFT::uint uintX_t
This is a value type class that represents a single section in the list of sections in the object fil...
ELFSymbolRef(const SymbolRef &B)
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.