14 #ifndef LLVM_OBJECT_ELFOBJECTFILE_H
15 #define LLVM_OBJECT_ELFOBJECTFILE_H
38 #include <system_error>
43 class elf_symbol_iterator;
45 class ELFRelocationRef;
103 assert(isa<ELFObjectFileBase>(B->getObject()));
191 uint16_t getEMachine()
const override;
192 uint64_t getSymbolSize(
DataRefImpl Sym)
const override;
258 auto RelSecOrErr = EF.getSection(Rel.d.a);
274 auto SectionsOrErr =
EF.sections();
275 if (!SectionsOrErr) {
280 uintptr_t SHT =
reinterpret_cast<uintptr_t
>((*SectionsOrErr).begin());
281 unsigned SymTableIndex =
282 (
reinterpret_cast<uintptr_t
>(SymTable) - SHT) /
sizeof(
Elf_Shdr);
284 DRI.
d.
a = SymTableIndex;
290 return reinterpret_cast<const Elf_Shdr *
>(Sec.
p);
295 DRI.
p =
reinterpret_cast<uintptr_t
>(Sec);
301 DRI.
p =
reinterpret_cast<uintptr_t
>(Dyn);
306 unsigned char Binding = ESym->getBinding();
307 unsigned char Visibility = ESym->getVisibility();
329 auto Ret =
EF.template getEntry<Elf_Sym>(Sym.
d.
a, Sym.
d.
b);
336 return reinterpret_cast<const Elf_Shdr *
>(Sec.
p);
352 unsigned getArch()
const override;
355 Result =
EF.getHeader()->e_flags;
356 return std::error_code();
377 template <
class ELFT>
382 template <
class ELFT>
385 auto SymTabOrErr =
EF.getSection(Sym.
d.
a);
387 return SymTabOrErr.takeError();
388 const Elf_Shdr *SymTableSec = *SymTabOrErr;
389 auto StrTabOrErr =
EF.getSection(SymTableSec->sh_link);
391 return StrTabOrErr.takeError();
392 const Elf_Shdr *StringTableSec = *StrTabOrErr;
393 auto SymStrTabOrErr =
EF.getStringTable(StringTableSec);
395 return SymStrTabOrErr.takeError();
396 return ESym->getName(*SymStrTabOrErr);
399 template <
class ELFT>
404 template <
class ELFT>
409 template <
class ELFT>
414 template <
class ELFT>
417 uint64_t
Ret = ESym->st_value;
430 template <
class ELFT>
435 switch (ESym->st_shndx) {
443 auto SymTabOrErr =
EF.getSection(Symb.
d.
a);
445 return SymTabOrErr.takeError();
446 const Elf_Shdr *SymTab = *SymTabOrErr;
449 auto SectionOrErr =
EF.getSection(ESym, SymTab, ShndxTable);
451 return SectionOrErr.takeError();
454 Result += Section->sh_addr;
460 template <
class ELFT>
464 return Sym->st_value;
468 template <
class ELFT>
470 return EF.getHeader()->e_machine;
473 template <
class ELFT>
478 template <
class ELFT>
483 template <
class ELFT>
488 template <
class ELFT>
493 template <
class ELFT>
498 switch (ESym->getType()) {
516 template <
class ELFT>
534 auto DotSymtabSecSyms =
EF.symbols(DotSymtabSec);
535 if (DotSymtabSecSyms && ESym == (*DotSymtabSecSyms).begin())
537 auto DotDynSymSecSyms =
EF.symbols(DotDynSymSec);
538 if (DotDynSymSecSyms && ESym == (*DotDynSymSecSyms).begin())
551 if (ESym->getType() ==
ELF::STT_FUNC && (ESym->st_value & 1) == 1)
561 if (isExportedToOtherDSO(ESym))
570 template <
class ELFT>
574 auto ESecOrErr =
EF.getSection(ESym, SymTab, ShndxTable);
576 return ESecOrErr.takeError();
580 return section_end();
583 Sec.
p =
reinterpret_cast<intptr_t>(ESec);
587 template <
class ELFT>
591 auto SymTabOrErr =
EF.getSection(Symb.
d.
a);
593 return SymTabOrErr.takeError();
594 const Elf_Shdr *SymTab = *SymTabOrErr;
595 return getSymbolSection(Sym, SymTab);
598 template <
class ELFT>
604 template <
class ELFT>
611 return std::error_code();
614 template <
class ELFT>
619 template <
class ELFT>
624 template <
class ELFT>
629 Result =
StringRef((
const char *)base() + EShdr->sh_offset, EShdr->sh_size);
630 return std::error_code();
633 template <
class ELFT>
638 template <
class ELFT>
643 template <
class ELFT>
648 template <
class ELFT>
655 template <
class ELFT>
662 template <
class ELFT>
667 template <
class ELFT>
671 auto SectionsOrErr =
EF.sections();
674 uintptr_t SHT =
reinterpret_cast<uintptr_t
>((*SectionsOrErr).begin());
675 RelData.
d.
a = (Sec.
p - SHT) /
EF.getHeader()->e_shentsize;
680 template <
class ELFT>
688 const Elf_Shdr *RelSec = getRelSection(RelData);
691 auto SymSecOrErr =
EF.getSection(RelSec->sh_link);
695 RelData.
d.
b += S->sh_size / S->sh_entsize;
699 template <
class ELFT>
703 return section_end();
708 return section_end();
710 auto R =
EF.getSection(EShdr->sh_info);
717 template <
class ELFT>
722 template <
class ELFT>
726 const Elf_Shdr *sec = getRelSection(Rel);
728 symbolIdx = getRel(Rel)->getSymbol(
EF.isMips64EL());
730 symbolIdx = getRela(Rel)->getSymbol(
EF.isMips64EL());
736 SymbolData.
d.
a = sec->sh_link;
737 SymbolData.
d.
b = symbolIdx;
741 template <
class ELFT>
744 "Only relocatable object files have relocation offsets");
745 const Elf_Shdr *sec = getRelSection(Rel);
747 return getRel(Rel)->r_offset;
749 return getRela(Rel)->r_offset;
752 template <
class ELFT>
754 const Elf_Shdr *sec = getRelSection(Rel);
756 return getRel(Rel)->getType(
EF.isMips64EL());
758 return getRela(Rel)->getType(
EF.isMips64EL());
761 template <
class ELFT>
766 template <
class ELFT>
769 uint32_t type = getRelocationType(Rel);
770 EF.getRelocationTypeName(type, Result);
773 template <
class ELFT>
778 return (int64_t)getRela(Rel)->r_addend;
781 template <
class ELFT>
785 auto Ret =
EF.template getEntry<Elf_Rel>(Rel.
d.
a, Rel.
d.
b);
791 template <
class ELFT>
795 auto Ret =
EF.template getEntry<Elf_Rela>(Rela.
d.
a, Rela.
d.
b);
801 template <
class ELFT>
804 getELFType(ELFT::TargetEndianness == support::
little, ELFT::Is64Bits),
806 EF(Data.getBuffer()) {
807 auto SectionsOrErr =
EF.sections();
808 if (!SectionsOrErr) {
812 for (
const Elf_Shdr &Sec : *SectionsOrErr) {
813 switch (Sec.sh_type) {
833 auto TableOrErr =
EF.getSHNDXTable(Sec);
845 template <
class ELFT>
851 template <
class ELFT>
853 const Elf_Shdr *SymTab = DotSymtabSec;
855 return symbol_begin();
860 template <
class ELFT>
866 template <
class ELFT>
868 const Elf_Shdr *SymTab = DotDynSymSec;
873 template <
class ELFT>
875 auto SectionsOrErr =
EF.sections();
881 template <
class ELFT>
883 auto SectionsOrErr =
EF.sections();
889 template <
class ELFT>
891 return ELFT::Is64Bits ? 8 : 4;
894 template <
class ELFT>
899 switch (
EF.getHeader()->e_machine) {
903 return "ELF32-iamcu";
905 return "ELF32-x86-64";
907 return (IsLittleEndian ?
"ELF32-arm-little" :
"ELF32-arm-big");
911 return "ELF32-hexagon";
913 return "ELF32-lanai";
919 return "ELF32-riscv";
922 return "ELF32-sparc";
926 return "ELF32-amdgpu";
928 return "ELF32-unknown";
931 switch (
EF.getHeader()->e_machine) {
935 return "ELF64-x86-64";
937 return (IsLittleEndian ?
"ELF64-aarch64-little" :
"ELF64-aarch64-big");
939 return "ELF64-ppc64";
941 return "ELF64-riscv";
945 return "ELF64-sparc";
953 "ELF64-amdgpu-hsacobj" :
"ELF64-amdgpu";
957 return "ELF64-unknown";
965 template <
class ELFT>
968 switch (
EF.getHeader()->e_machine) {
1024 && IsLittleEndian) ?
1035 template <
class ELFT>
1038 return make_range(dynamic_symbol_begin(), dynamic_symbol_end());
1048 #endif // LLVM_OBJECT_ELFOBJECTFILE_H
void getRelocationTypeName(DataRefImpl Rel, SmallVectorImpl< char > &Result) const override
uint64_t getSectionSize(DataRefImpl Sec) const override
Represents either an error or a value T.
virtual uint16_t getEMachine() const =0
static uint64_t getSymbolValue(const MCSymbol &Symbol, const MCAsmLayout &Layout)
ELFObjectFile< ELFType< support::little, false > > ELF32LEObjectFile
static bool classof(const Binary *v)
DataRefImpl getRawDataRefImpl() const
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
bool isSectionBSS(DataRefImpl Sec) const override
const ObjectFile * getObject() const
bool isSectionText(DataRefImpl Sec) const override
elf_relocation_iterator(const relocation_iterator &B)
SubtargetFeatures getFeatures() const override
ELFFile< ELFT >::Elf_Rela Elf_Rela
This provides a very simple, boring adaptor for a begin and end iterator into a range type...
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
bool isRelocatableObject() const override
True if this is a relocatable object (.o/.obj).
Expected< StringRef > getSymbolName(DataRefImpl Symb) const override
This class is the base class for all object file types.
const Elf_Shdr * toELFShdrIter(DataRefImpl Sec) const
ELFYAML::ELF_STV Visibility
struct llvm::object::DataRefImpl::@119 d
DataRefImpl getRawDataRefImpl() const
bool isSectionVirtual(DataRefImpl Sec) const override
uint32_t getSectionType(DataRefImpl Sec) const override
DataRefImpl toDRI(const Elf_Shdr *Sec) const
const ELFObjectFileBase * getObject() const
ELFObjectFile< ELFType< support::little, true > > ELF64LEObjectFile
void moveRelocationNext(DataRefImpl &Rel) const override
basic_symbol_iterator symbol_begin() const override
symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override
virtual basic_symbol_iterator symbol_begin() const =0
ELFObjectFile< ELFType< support::big, false > > ELF32BEObjectFile
uint8_t getSymbolOther(DataRefImpl Symb) const override
ELFFile< ELFT >::Elf_Sym Elf_Sym
ErrorOr< int64_t > getRelocationAddend(DataRefImpl Rel) const override
uint8_t getELFType() const
const Elf_Shdr * DotSymtabSec
uint64_t getSectionAlignment(DataRefImpl Sec) const override
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...
elf_section_iterator(const section_iterator &B)
const ELFRelocationRef * operator->() const
Tagged union holding either a T or a Error.
Expected< const typename ELFT::Shdr * > getSection(typename ELFT::ShdrRange Sections, uint32_t Index)
uint64_t getSymbolValueImpl(DataRefImpl Symb) const override
const Elf_Rela * getRela(DataRefImpl Rela) const
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
uint8_t getBytesInAddress() const override
The number of bytes used to represent an address in this object file format.
section_iterator section_begin() const override
std::error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const override
void moveSectionNext(DataRefImpl &Sec) const override
elf_symbol_iterator_range getDynamicSymbolIterators() const override
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
elf_symbol_iterator dynamic_symbol_begin() const
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
const Elf_Rel * getRel(DataRefImpl Rel) const
const Elf_Sym * getSymbol(DataRefImpl Sym) const
const ELFFile< ELFT > * getELFFile() const
ArrayRef< Elf_Word > ShndxTable
const SymbolRef * operator->() 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)
relocation_iterator section_rel_end(DataRefImpl Sec) const override
DataRefImpl toDRI(const Elf_Dyn *Dyn) const
content_iterator< SectionRef > section_iterator
DataRefImpl toDRI(const Elf_Shdr *SymTable, unsigned SymbolNum) const
ELFRelocationRef(const RelocationRef &B)
unsigned int getType() const
static bool classof(const Binary *v)
elf_symbol_iterator_range symbols() const
const ELFSymbolRef & operator*() const
The instances of the Type class are immutable: once they are created, they are never changed...
uint32_t getSymbolFlags(DataRefImpl Symb) const override
virtual uint64_t getSectionFlags(DataRefImpl Sec) const =0
ELFFile< ELFT >::Elf_Ehdr Elf_Ehdr
const Elf_Shdr * DotDynSymSec
static unsigned int getELFType(bool isLE, bool is64Bits)
section_iterator getRelocatedSection(DataRefImpl Sec) const override
uint32_t getSymbolAlignment(DataRefImpl Symb) const override
bool isSectionData(DataRefImpl Sec) const override
virtual basic_symbol_iterator symbol_end() const =0
ELFFile< ELFT >::Elf_Dyn Elf_Dyn
virtual ErrorOr< int64_t > getRelocationAddend(DataRefImpl Rel) const =0
const ELFSectionRef * operator->() const
content_iterator< RelocationRef > relocation_iterator
uint8_t getSymbolELFType(DataRefImpl Symb) const override
StringRef getFileFormatName() const override
void consumeError(Error Err)
Consume a Error without doing anything.
const ELFSectionRef & operator*() const
std::error_code getPlatformFlags(unsigned &Result) const override
Returns platform-specific object flags, if any.
const ObjectFile * getObject() const
uint64_t getSectionAddress(DataRefImpl Sec) const override
std::error_code getSectionName(DataRefImpl Sec, StringRef &Res) const override
uint64_t getRelocationOffset(DataRefImpl Rel) const override
const Elf_Shdr * getSection(DataRefImpl Sec) const
content_iterator< BasicSymbolRef > basic_symbol_iterator
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type)
unsigned getArch() const override
uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override
Expected< section_iterator > getSymbolSection(const Elf_Sym *Symb, const Elf_Shdr *SymTab) const
const ObjectFile * getObject() const
ErrorOr< int64_t > getAddend() const
uint64_t getSectionFlags(DataRefImpl Sec) const override
Expected< uint64_t > getSymbolAddress(DataRefImpl Symb) const override
const ELFRelocationRef & operator*() const
ELFObjectFile< ELFType< support::big, true > > ELF64BEObjectFile
const ELFSymbolRef * operator->() const
ELFObjectFile(MemoryBufferRef Object, std::error_code &EC)
A range adaptor for a pair of iterators.
SubtargetFeatures - Manages the enabling and disabling of subtarget specific features.
virtual uint64_t getSymbolSize(DataRefImpl Symb) const =0
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
iterator_range< elf_symbol_iterator > elf_symbol_iterator_range
bool isExportedToOtherDSO(const Elf_Sym *ESym) const
basic_symbol_iterator symbol_end() const override
bool isSectionCompressed(DataRefImpl Sec) const override
ELFSectionRef(const SectionRef &B)
const SymbolicFile * getObject() const
uint64_t getSectionOffset(DataRefImpl Sec) const override
virtual uint32_t getSectionType(DataRefImpl Sec) const =0
ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source)
const SymbolRef & operator*() const
section_iterator section_end() const override
Provides ErrorOr<T> smart pointer.
const content_type & operator*() const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
const Elf_Shdr * getRelSection(DataRefImpl Rel) const
Get the relocation section that contains Rel.
const content_type * operator->() const
virtual elf_symbol_iterator_range getDynamicSymbolIterators() const =0
const ELFObjectFileBase * getObject() const
ELFFile< ELFT >::Elf_Shdr Elf_Shdr
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
const ELFObjectFileBase * getObject() const
virtual uint8_t getSymbolOther(DataRefImpl Symb) const =0
uint64_t getOffset() const
elf_symbol_iterator(const basic_symbol_iterator &B)
std::error_code errorToErrorCode(Error Err)
Helper for converting an ECError to a std::error_code.
ELFFile< ELFT >::uintX_t uintX_t
ELFFile< ELFT >::Elf_Rel Elf_Rel
This is a value type class that represents a single section in the list of sections in the object fil...
uint64_t getFlags() const
ELFSymbolRef(const SymbolRef &B)
elf_symbol_iterator dynamic_symbol_end() const
DataRefImpl getRawDataRefImpl() const