13#ifndef LLVM_OBJECT_ELFOBJECTFILE_H
14#define LLVM_OBJECT_ELFOBJECTFILE_H
42template <
typename T>
class SmallVectorImpl;
100 std::vector<std::pair<std::optional<DataRefImpl>,
uint64_t>>
111 readBBAddrMap(std::optional<unsigned> TextSectionIndex = std::nullopt)
const;
140 assert(isa<ELFObjectFileBase>(
B->getObject()));
181 if (EE.Value ==
Type) {
242 uint16_t getEMachine()
const override;
264 bool ContentValid =
false;
287 const Elf_Shdr *SymTab)
const;
334 auto SectionsOrErr =
EF.sections();
335 if (!SectionsOrErr) {
340 uintptr_t SHT =
reinterpret_cast<uintptr_t
>((*SectionsOrErr).begin());
341 unsigned SymTableIndex =
342 (
reinterpret_cast<uintptr_t
>(SymTable) - SHT) /
sizeof(Elf_Shdr);
344 DRI.
d.
a = SymTableIndex;
350 return reinterpret_cast<const Elf_Shdr *
>(Sec.
p);
355 DRI.
p =
reinterpret_cast<uintptr_t
>(Sec);
361 DRI.
p =
reinterpret_cast<uintptr_t
>(Dyn);
366 unsigned char Binding = ESym->getBinding();
367 unsigned char Visibility = ESym->getVisibility();
379 auto SectionsOrErr =
EF.sections();
381 return SectionsOrErr.takeError();
383 for (
const Elf_Shdr &Sec : *SectionsOrErr) {
386 auto ErrorOrContents =
EF.getSectionContents(Sec);
387 if (!ErrorOrContents)
388 return ErrorOrContents.takeError();
390 auto Contents = ErrorOrContents.get();
410 bool InitContent =
true);
416 return EF.template getEntry<Elf_Sym>(Sym.
d.
a, Sym.
d.
b);
421 auto RelSecOrErr =
EF.getSection(Rel.
d.
a);
429 return reinterpret_cast<const Elf_Shdr *
>(Sec.
p);
478 auto SectionsOrErr = EF.sections();
480 return SectionsOrErr.takeError();
482 for (
const Elf_Shdr &Sec : *SectionsOrErr) {
483 switch (Sec.sh_type) {
495 if (!DotSymtabShndxSec)
496 DotSymtabShndxSec = &Sec;
511 auto SymTabOrErr = EF.getSection(Sym.
d.
a);
513 return SymTabOrErr.takeError();
514 const Elf_Shdr *SymTableSec = *SymTabOrErr;
515 auto StrTabOrErr = EF.getSection(SymTableSec->sh_link);
517 return StrTabOrErr.takeError();
518 const Elf_Shdr *StringTableSec = *StrTabOrErr;
519 auto SymStrTabOrErr = EF.getStringTable(*StringTableSec);
521 return SymStrTabOrErr.takeError();
530 return (*SecOrErr)->getName();
557 uint64_t Ret = (*SymOrErr)->st_value;
561 const Elf_Ehdr &Header = EF.getHeader();
574 if (!SymbolValueOrErr)
578 uint64_t Result = *SymbolValueOrErr;
583 switch ((*SymOrErr)->st_shndx) {
590 auto SymTabOrErr = EF.getSection(Symb.
d.
a);
592 return SymTabOrErr.takeError();
596 if (DotSymtabShndxSec) {
599 EF.getSHNDXTable(*DotSymtabShndxSec))
600 ShndxTable = *ShndxTableOrErr;
602 return ShndxTableOrErr.takeError();
606 EF.getSection(**SymOrErr, *SymTabOrErr, ShndxTable);
609 const Elf_Shdr *Section = *SectionOrErr;
611 Result += Section->sh_addr;
623 return (*SymOrErr)->st_value;
629 return EF.getHeader().e_machine;
632template <
class ELFT>
uint16_t ELFObjectFile<ELFT>::getEType()
const {
633 return EF.getHeader().e_type;
637uint64_t ELFObjectFile<ELFT>::getSymbolSize(DataRefImpl Sym)
const {
638 Expected<const Elf_Sym *> SymOrErr = getSymbol(Sym);
641 return (*SymOrErr)->st_size;
646 return getSymbolSize(Symb);
654 return (*SymOrErr)->getBinding();
662 return (*SymOrErr)->st_other;
670 return (*SymOrErr)->getType();
680 switch ((*SymOrErr)->getType()) {
704 const Elf_Sym *ESym = *SymOrErr;
720 EF.symbols(DotSymtabSec)) {
722 if (ESym == SymbolsOrErr->begin())
726 return SymbolsOrErr.takeError();
729 EF.symbols(DotDynSymSec)) {
731 if (ESym == SymbolsOrErr->begin())
735 return SymbolsOrErr.takeError();
740 if (
Name.startswith(
"$d") ||
Name.startswith(
"$x"))
746 }
else if (EF.getHeader().e_machine ==
ELF::EM_ARM) {
750 if (
Name.empty() ||
Name.startswith(
"$d") ||
Name.startswith(
"$t") ||
751 Name.startswith(
"$a"))
757 if (ESym->getType() ==
ELF::STT_FUNC && (ESym->st_value & 1) == 1)
762 if (NameOrErr->empty())
776 if (isExportedToOtherDSO(ESym))
791 const Elf_Shdr *SymTab)
const {
793 if (DotSymtabShndxSec) {
796 EF.getSHNDXTable(*DotSymtabShndxSec);
797 if (!ShndxTableOrErr)
799 ShndxTable = *ShndxTableOrErr;
802 auto ESecOrErr = EF.getSection(*ESym, SymTab, ShndxTable);
806 const Elf_Shdr *ESec = *ESecOrErr;
808 return section_end();
811 Sec.
p =
reinterpret_cast<intptr_t
>(ESec);
822 auto SymTabOrErr = EF.getSection(Symb.
d.
a);
824 return SymTabOrErr.takeError();
825 return getSymbolSection(*SymOrErr, *SymTabOrErr);
846 auto SectionsOrErr = EF.sections();
849 llvm_unreachable(
"unable to get section index");
851 const Elf_Shdr *First = SectionsOrErr->begin();
865 return ArrayRef((
const uint8_t *)base(), (
size_t)0);
867 checkOffset(getMemoryBufferRef(),
868 (uintptr_t)base() + EShdr->sh_offset, EShdr->sh_size))
870 return ArrayRef((
const uint8_t *)base() + EShdr->sh_offset, EShdr->sh_size);
904std::vector<SectionRef>
906 std::vector<SectionRef> Res;
907 std::vector<uintptr_t> Offsets;
909 auto SectionsOrErr = EF.sections();
913 for (
const Elf_Shdr &Sec : *SectionsOrErr) {
917 reinterpret_cast<Elf_Dyn *
>((uintptr_t)base() + Sec.sh_offset);
919 if (
Dynamic->d_tag == ELF::DT_REL ||
Dynamic->d_tag == ELF::DT_RELA ||
920 Dynamic->d_tag == ELF::DT_JMPREL) {
921 Offsets.push_back(
Dynamic->d_un.d_val);
925 for (
const Elf_Shdr &Sec : *SectionsOrErr) {
927 Res.emplace_back(toDRI(&Sec),
this);
954 if (!SectionNameOrErr) {
968 auto SectionsOrErr = EF.sections();
971 uintptr_t SHT =
reinterpret_cast<uintptr_t
>((*SectionsOrErr).begin());
972 RelData.
d.
a = (Sec.
p - SHT) / EF.getHeader().e_shentsize;
980 const Elf_Shdr *S =
reinterpret_cast<const Elf_Shdr *
>(Sec.
p);
985 const Elf_Shdr *RelSec = getRelSection(RelData);
988 auto SymSecOrErr = EF.getSection(RelSec->sh_link);
993 RelData.
d.
b += S->sh_size / S->sh_entsize;
1001 uintX_t
Type = EShdr->sh_type;
1003 return section_end();
1012template <
class ELFT>
1017template <
class ELFT>
1021 const Elf_Shdr *sec = getRelSection(Rel);
1023 symbolIdx = getRel(Rel)->getSymbol(EF.isMips64EL());
1025 symbolIdx = getRela(Rel)->getSymbol(EF.isMips64EL());
1027 return symbol_end();
1031 SymbolData.
d.
a = sec->sh_link;
1032 SymbolData.
d.
b = symbolIdx;
1036template <
class ELFT>
1038 const Elf_Shdr *sec = getRelSection(Rel);
1040 return getRel(Rel)->r_offset;
1042 return getRela(Rel)->r_offset;
1045template <
class ELFT>
1047 const Elf_Shdr *sec = getRelSection(Rel);
1049 return getRel(Rel)->getType(EF.isMips64EL());
1051 return getRela(Rel)->getType(EF.isMips64EL());
1054template <
class ELFT>
1059template <
class ELFT>
1062 uint32_t type = getRelocationType(Rel);
1063 EF.getRelocationTypeName(type, Result);
1066template <
class ELFT>
1071 return (int64_t)getRela(Rel)->r_addend;
1074template <
class ELFT>
1078 auto Ret = EF.template getEntry<Elf_Rel>(Rel.
d.
a, Rel.
d.
b);
1084template <
class ELFT>
1088 auto Ret = EF.template getEntry<Elf_Rela>(Rela.
d.
a, Rela.
d.
b);
1094template <
class ELFT>
1098 if (
Error E = EFOrErr.takeError())
1099 return std::move(
E);
1105 return std::move(
E);
1106 return std::move(Obj);
1109template <
class ELFT>
1111 const Elf_Shdr *DotDynSymSec,
1112 const Elf_Shdr *DotSymtabSec,
1113 const Elf_Shdr *DotSymtabShndx)
1115 getELFType(ELFT::TargetEndianness == support::little, ELFT::Is64Bits),
1117 EF(EF), DotDynSymSec(DotDynSymSec), DotSymtabSec(DotSymtabSec),
1118 DotSymtabShndxSec(DotSymtabShndx) {}
1120template <
class ELFT>
1123 Other.DotSymtabSec,
Other.DotSymtabShndxSec) {}
1125template <
class ELFT>
1129 DotSymtabSec && DotSymtabSec->sh_size >=
sizeof(Elf_Sym) ? 1 : 0);
1133template <
class ELFT>
1135 const Elf_Shdr *SymTab = DotSymtabSec;
1137 return symbol_begin();
1138 DataRefImpl Sym = toDRI(SymTab, SymTab->sh_size /
sizeof(Elf_Sym));
1142template <
class ELFT>
1144 if (!DotDynSymSec || DotDynSymSec->sh_size <
sizeof(Elf_Sym))
1152template <
class ELFT>
1154 const Elf_Shdr *SymTab = DotDynSymSec;
1156 return dynamic_symbol_begin();
1157 DataRefImpl Sym = toDRI(SymTab, SymTab->sh_size /
sizeof(Elf_Sym));
1161template <
class ELFT>
1163 auto SectionsOrErr = EF.sections();
1169template <
class ELFT>
1171 auto SectionsOrErr = EF.sections();
1177template <
class ELFT>
1179 return ELFT::Is64Bits ? 8 : 4;
1182template <
class ELFT>
1184 constexpr bool IsLittleEndian = ELFT::TargetEndianness ==
support::little;
1187 switch (EF.getHeader().e_machine) {
1189 return "elf32-m68k";
1191 return "elf32-i386";
1193 return "elf32-iamcu";
1195 return "elf32-x86-64";
1197 return (IsLittleEndian ?
"elf32-littlearm" :
"elf32-bigarm");
1201 return "elf32-hexagon";
1203 return "elf32-lanai";
1205 return "elf32-mips";
1207 return "elf32-msp430";
1209 return (IsLittleEndian ?
"elf32-powerpcle" :
"elf32-powerpc");
1211 return "elf32-littleriscv";
1213 return "elf32-csky";
1216 return "elf32-sparc";
1218 return "elf32-amdgpu";
1220 return "elf32-loongarch";
1222 return "elf32-xtensa";
1224 return "elf32-unknown";
1227 switch (EF.getHeader().e_machine) {
1229 return "elf64-i386";
1231 return "elf64-x86-64";
1233 return (IsLittleEndian ?
"elf64-littleaarch64" :
"elf64-bigaarch64");
1235 return (IsLittleEndian ?
"elf64-powerpcle" :
"elf64-powerpc");
1237 return "elf64-littleriscv";
1239 return "elf64-s390";
1241 return "elf64-sparc";
1243 return "elf64-mips";
1245 return "elf64-amdgpu";
1251 return "elf64-loongarch";
1253 return "elf64-unknown";
1263 switch (EF.getHeader().e_machine) {
1315 if (!IsLittleEndian)
1355template <
class ELFT>
1357 return EF.getHeader().e_entry;
1360template <
class ELFT>
1363 return make_range(dynamic_symbol_begin(), dynamic_symbol_end());
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static StringRef getSymbolName(SymbolKind SymKind)
#define LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static uint64_t getSymbolValue(const MCSymbol &Symbol, const MCAsmLayout &Layout)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Base class for error info classes.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
reference get()
Returns a reference to the stored T value.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
StringRef - Represent a constant reference to a string, i.e.
Manages the enabling and disabling of subtarget specific features.
Triple - Helper class for working with autoconf configuration names.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
A range adaptor for a pair of iterators.
const SymbolicFile * getObject() const
DataRefImpl getRawDataRefImpl() const
static unsigned int getELFType(bool isLE, bool is64Bits)
static Expected< ELFFile > create(StringRef Object)
virtual uint64_t getSymbolSize(DataRefImpl Symb) const =0
std::vector< std::pair< std::optional< DataRefImpl >, uint64_t > > getPltAddresses() const
Expected< std::vector< BBAddrMap > > readBBAddrMap(std::optional< unsigned > TextSectionIndex=std::nullopt) const
Returns a vector of all BB address maps in the object file. When.
virtual Error getBuildAttributes(ELFAttributeParser &Attributes) const =0
virtual uint64_t getSectionFlags(DataRefImpl Sec) const =0
virtual uint16_t getEType() const =0
virtual uint8_t getSymbolELFType(DataRefImpl Symb) const =0
Expected< std::vector< VersionEntry > > readDynsymVersions() const
Returns a vector containing a symbol version for each dynamic symbol.
virtual uint8_t getSymbolOther(DataRefImpl Symb) const =0
virtual elf_symbol_iterator_range getDynamicSymbolIterators() const =0
virtual uint32_t getSectionType(DataRefImpl Sec) const =0
friend class ELFSymbolRef
elf_symbol_iterator_range symbols() const
virtual Expected< int64_t > getRelocationAddend(DataRefImpl Rel) const =0
Expected< SubtargetFeatures > getFeatures() const override
virtual uint8_t getSymbolBinding(DataRefImpl Symb) const =0
std::optional< StringRef > tryGetCPUName() const override
iterator_range< elf_symbol_iterator > elf_symbol_iterator_range
virtual uint16_t getEMachine() const =0
static bool classof(const Binary *v)
virtual unsigned getPlatformFlags() const =0
Returns platform-specific object flags, if any.
void setARMSubArch(Triple &TheTriple) const override
virtual uint64_t getSectionOffset(DataRefImpl Sec) const =0
static bool classof(const Binary *v)
const ELFFile< ELFT > & getELFFile() const
Expected< StringRef > getSectionName(DataRefImpl Sec) const override
std::vector< SectionRef > dynamic_relocation_sections() const override
uint64_t getRelocationType(DataRefImpl Rel) const override
bool isSectionText(DataRefImpl Sec) const override
uint8_t getSymbolELFType(DataRefImpl Symb) const override
uint64_t getSectionAlignment(DataRefImpl Sec) const override
bool is64Bit() const override
DataRefImpl toDRI(const Elf_Dyn *Dyn) const
bool isSectionVirtual(DataRefImpl Sec) const override
SectionRef toSectionRef(const Elf_Shdr *Sec) const
bool IsContentValid() const
uint32_t getSectionType(DataRefImpl Sec) const override
symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override
elf_symbol_iterator_range getDynamicSymbolIterators() const override
void createFakeSections()
Expected< const Elf_Sym * > getSymbol(DataRefImpl Sym) const
const Elf_Rel * getRel(DataRefImpl Rel) const
Expected< section_iterator > getSymbolSection(const Elf_Sym *Symb, const Elf_Shdr *SymTab) const
uint64_t getSymbolValueImpl(DataRefImpl Symb) const override
basic_symbol_iterator symbol_begin() const override
Expected< uint64_t > getSymbolAddress(DataRefImpl Symb) const override
ELFSymbolRef toSymbolRef(const Elf_Shdr *SymTable, unsigned SymbolNum) const
const Elf_Rela * getRela(DataRefImpl Rela) const
static Expected< ELFObjectFile< ELFT > > create(MemoryBufferRef Object, bool InitContent=true)
bool isExportedToOtherDSO(const Elf_Sym *ESym) const
uint64_t getSectionAddress(DataRefImpl Sec) const override
Expected< ArrayRef< uint8_t > > getSectionContents(DataRefImpl Sec) const override
void getRelocationTypeName(DataRefImpl Rel, SmallVectorImpl< char > &Result) const override
uint64_t getSectionIndex(DataRefImpl Sec) const override
Expected< uint32_t > getSymbolFlags(DataRefImpl Symb) const override
bool isSectionData(DataRefImpl Sec) const override
const Elf_Shdr * DotSymtabSec
const Elf_Shdr * DotDynSymSec
uint32_t getSymbolAlignment(DataRefImpl Symb) const override
const Elf_Shdr * toELFShdrIter(DataRefImpl Sec) const
Triple::ArchType getArch() const override
uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override
uint64_t getSectionSize(DataRefImpl Sec) const override
bool isBerkeleyData(DataRefImpl Sec) const override
StringRef getFileFormatName() const override
bool isRelocatableObject() const override
True if this is a relocatable object (.o/.obj).
void moveSymbolNext(DataRefImpl &Symb) const override
uint8_t getSymbolOther(DataRefImpl Symb) const override
section_iterator section_end() const override
const Elf_Shdr * getRelSection(DataRefImpl Rel) const
Get the relocation section that contains Rel.
Expected< int64_t > getRelocationAddend(DataRefImpl Rel) const override
uint64_t getRelocationOffset(DataRefImpl Rel) const override
Expected< section_iterator > getRelocatedSection(DataRefImpl Sec) const override
void moveSectionNext(DataRefImpl &Sec) const override
bool isSectionBSS(DataRefImpl Sec) const override
unsigned getPlatformFlags() const override
Returns platform-specific object flags, if any.
uint64_t getSectionFlags(DataRefImpl Sec) const override
void moveRelocationNext(DataRefImpl &Rel) const override
relocation_iterator section_rel_begin(DataRefImpl Sec) const override
Expected< StringRef > getSymbolName(DataRefImpl Symb) const override
Error initContent() override
basic_symbol_iterator symbol_end() const override
uint8_t getSymbolBinding(DataRefImpl Symb) const override
uint64_t getSectionOffset(DataRefImpl Sec) const override
relocation_iterator section_rel_end(DataRefImpl Sec) const override
Expected< SymbolRef::Type > getSymbolType(DataRefImpl Symb) const override
const Elf_Shdr * getSection(DataRefImpl Sec) const
Error getBuildAttributes(ELFAttributeParser &Attributes) const override
DataRefImpl toDRI(const Elf_Shdr *Sec) const
elf_symbol_iterator dynamic_symbol_begin() const
const Elf_Shdr * DotSymtabShndxSec
elf_symbol_iterator dynamic_symbol_end() const
DataRefImpl toDRI(const Elf_Shdr *SymTable, unsigned SymbolNum) const
bool isDebugSection(DataRefImpl Sec) const override
section_iterator section_begin() const override
bool isSectionCompressed(DataRefImpl Sec) const override
bool isBerkeleyText(DataRefImpl Sec) const override
uint8_t getBytesInAddress() const override
The number of bytes used to represent an address in this object file format.
Expected< uint64_t > getStartAddress() const override
Expected< int64_t > getAddend() const
const ELFObjectFileBase * getObject() const
ELFRelocationRef(const RelocationRef &B)
uint64_t getFlags() const
const ELFObjectFileBase * getObject() const
uint64_t getOffset() const
ELFSectionRef(const SectionRef &B)
const ELFObjectFileBase * getObject() const
uint8_t getELFType() const
ELFSymbolRef(const SymbolRef &B)
uint8_t getBinding() const
StringRef getELFTypeName() const
This class is the base class for all object file types.
This is a value type class that represents a single relocation in the list of relocations in the obje...
const ObjectFile * getObject() const
DataRefImpl getRawDataRefImpl() const
This is a value type class that represents a single section in the list of sections in the object fil...
DataRefImpl getRawDataRefImpl() const
const ObjectFile * getObject() const
This is a value type class that represents a single symbol in the list of symbols in the object file.
const ObjectFile * getObject() const
virtual basic_symbol_iterator symbol_begin() const =0
virtual basic_symbol_iterator symbol_end() const =0
const content_type & operator*() const
const content_type * operator->() const
const ELFRelocationRef & operator*() const
elf_relocation_iterator(const relocation_iterator &B)
const ELFRelocationRef * operator->() const
elf_section_iterator(const section_iterator &B)
const ELFSectionRef * operator->() const
const ELFSectionRef & operator*() const
const ELFSymbolRef & operator*() const
elf_symbol_iterator(const basic_symbol_iterator &B)
const ELFSymbolRef * operator->() const
const SymbolRef * operator->() const
const SymbolRef & operator*() const
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
@ EF_AMDGPU_MACH_AMDGCN_LAST
@ EF_AMDGPU_MACH_R600_LAST
@ EF_AMDGPU_MACH_AMDGCN_FIRST
@ EF_AMDGPU_MACH_R600_FIRST
static Expected< const T * > getObject(MemoryBufferRef M, const void *Ptr, const uint64_t Size=sizeof(T))
Expected< const typename ELFT::Shdr * > getSection(typename ELFT::ShdrRange Sections, uint32_t Index)
Error createError(const Twine &Err)
StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type)
constexpr int NumElfSymbolTypes
content_iterator< SectionRef > section_iterator
content_iterator< RelocationRef > relocation_iterator
content_iterator< BasicSymbolRef > basic_symbol_iterator
const llvm::EnumEntry< unsigned > ElfSymbolTypes[NumElfSymbolTypes]
This is an optimization pass for GlobalISel generic memory operations.
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
@ Dynamic
Denotes mode unknown at compile time.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
std::error_code errorToErrorCode(Error Err)
Helper for converting an ECError to a std::error_code.
void consumeError(Error Err)
Consume a Error without doing anything.
struct llvm::object::DataRefImpl::@339 d