summaryrefslogtreecommitdiff
path: root/include/llvm/Object/ELFObjectFile.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/Object/ELFObjectFile.h')
-rw-r--r--include/llvm/Object/ELFObjectFile.h109
1 files changed, 72 insertions, 37 deletions
diff --git a/include/llvm/Object/ELFObjectFile.h b/include/llvm/Object/ELFObjectFile.h
index 40503cb6bb9d..2c0905d545a7 100644
--- a/include/llvm/Object/ELFObjectFile.h
+++ b/include/llvm/Object/ELFObjectFile.h
@@ -15,6 +15,7 @@
#define LLVM_OBJECT_ELFOBJECTFILE_H
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
@@ -67,6 +68,9 @@ public:
virtual elf_symbol_iterator_range getDynamicSymbolIterators() const = 0;
+ /// Returns platform-specific object flags, if any.
+ virtual unsigned getPlatformFlags() const = 0;
+
elf_symbol_iterator_range symbols() const;
static bool classof(const Binary *v) { return v->isELF(); }
@@ -77,7 +81,11 @@ public:
SubtargetFeatures getARMFeatures() const;
+ SubtargetFeatures getRISCVFeatures() const;
+
void setARMSubArch(Triple &TheTriple) const override;
+
+ virtual uint16_t getEType() const = 0;
};
class ELFSectionRef : public SectionRef {
@@ -195,19 +203,20 @@ ELFObjectFileBase::symbols() const {
template <class ELFT> class ELFObjectFile : public ELFObjectFileBase {
uint16_t getEMachine() const override;
+ uint16_t getEType() const override;
uint64_t getSymbolSize(DataRefImpl Sym) const override;
public:
LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
- using uintX_t = typename ELFFile<ELFT>::uintX_t;
+ using uintX_t = typename ELFT::uint;
- using Elf_Sym = typename ELFFile<ELFT>::Elf_Sym;
- using Elf_Shdr = typename ELFFile<ELFT>::Elf_Shdr;
- using Elf_Ehdr = typename ELFFile<ELFT>::Elf_Ehdr;
- using Elf_Rel = typename ELFFile<ELFT>::Elf_Rel;
- using Elf_Rela = typename ELFFile<ELFT>::Elf_Rela;
- using Elf_Dyn = typename ELFFile<ELFT>::Elf_Dyn;
+ using Elf_Sym = typename ELFT::Sym;
+ using Elf_Shdr = typename ELFT::Shdr;
+ using Elf_Ehdr = typename ELFT::Ehdr;
+ using Elf_Rel = typename ELFT::Rel;
+ using Elf_Rela = typename ELFT::Rela;
+ using Elf_Dyn = typename ELFT::Dyn;
private:
ELFObjectFile(MemoryBufferRef Object, ELFFile<ELFT> EF,
@@ -251,6 +260,7 @@ protected:
bool isSectionVirtual(DataRefImpl Sec) const override;
relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
relocation_iterator section_rel_end(DataRefImpl Sec) const override;
+ std::vector<SectionRef> dynamic_relocation_sections() const override;
section_iterator getRelocatedSection(DataRefImpl Sec) const override;
void moveRelocationNext(DataRefImpl &Rel) const override;
@@ -265,7 +275,7 @@ protected:
uint64_t getSectionOffset(DataRefImpl Sec) const override;
StringRef getRelocationTypeName(uint32_t Type) const;
- /// \brief Get the relocation section that contains \a Rel.
+ /// Get the relocation section that contains \a Rel.
const Elf_Shdr *getRelSection(DataRefImpl Rel) const {
auto RelSecOrErr = EF.getSection(Rel.d.a);
if (!RelSecOrErr)
@@ -363,11 +373,9 @@ public:
uint8_t getBytesInAddress() const override;
StringRef getFileFormatName() const override;
Triple::ArchType getArch() const override;
+ Expected<uint64_t> getStartAddress() const override;
- std::error_code getPlatformFlags(unsigned &Result) const override {
- Result = EF.getHeader()->e_flags;
- return std::error_code();
- }
+ unsigned getPlatformFlags() const override { return EF.getHeader()->e_flags; }
std::error_code getBuildAttributes(ARMAttributeParser &Attributes) const override {
auto SectionsOrErr = EF.sections();
@@ -404,10 +412,10 @@ public:
bool isRelocatableObject() const override;
};
-using ELF32LEObjectFile = ELFObjectFile<ELFType<support::little, false>>;
-using ELF64LEObjectFile = ELFObjectFile<ELFType<support::little, true>>;
-using ELF32BEObjectFile = ELFObjectFile<ELFType<support::big, false>>;
-using ELF64BEObjectFile = ELFObjectFile<ELFType<support::big, true>>;
+using ELF32LEObjectFile = ELFObjectFile<ELF32LE>;
+using ELF64LEObjectFile = ELFObjectFile<ELF64LE>;
+using ELF32BEObjectFile = ELFObjectFile<ELF32BE>;
+using ELF64BEObjectFile = ELFObjectFile<ELF64BE>;
template <class ELFT>
void ELFObjectFile<ELFT>::moveSymbolNext(DataRefImpl &Sym) const {
@@ -505,6 +513,10 @@ uint16_t ELFObjectFile<ELFT>::getEMachine() const {
return EF.getHeader()->e_machine;
}
+template <class ELFT> uint16_t ELFObjectFile<ELFT>::getEType() const {
+ return EF.getHeader()->e_type;
+}
+
template <class ELFT>
uint64_t ELFObjectFile<ELFT>::getSymbolSize(DataRefImpl Sym) const {
return getSymbol(Sym)->st_size;
@@ -698,8 +710,9 @@ bool ELFObjectFile<ELFT>::isSectionText(DataRefImpl Sec) const {
template <class ELFT>
bool ELFObjectFile<ELFT>::isSectionData(DataRefImpl Sec) const {
const Elf_Shdr *EShdr = getSection(Sec);
- return EShdr->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) &&
- EShdr->sh_type == ELF::SHT_PROGBITS;
+ return EShdr->sh_type == ELF::SHT_PROGBITS &&
+ EShdr->sh_flags & ELF::SHF_ALLOC &&
+ !(EShdr->sh_flags & ELF::SHF_EXECINSTR);
}
template <class ELFT>
@@ -710,6 +723,35 @@ bool ELFObjectFile<ELFT>::isSectionBSS(DataRefImpl Sec) const {
}
template <class ELFT>
+std::vector<SectionRef>
+ELFObjectFile<ELFT>::dynamic_relocation_sections() const {
+ std::vector<SectionRef> Res;
+ std::vector<uintptr_t> Offsets;
+
+ auto SectionsOrErr = EF.sections();
+ if (!SectionsOrErr)
+ return Res;
+
+ for (const Elf_Shdr &Sec : *SectionsOrErr) {
+ if (Sec.sh_type != ELF::SHT_DYNAMIC)
+ continue;
+ Elf_Dyn *Dynamic =
+ reinterpret_cast<Elf_Dyn *>((uintptr_t)base() + Sec.sh_offset);
+ for (; Dynamic->d_tag != ELF::DT_NULL; Dynamic++) {
+ if (Dynamic->d_tag == ELF::DT_REL || Dynamic->d_tag == ELF::DT_RELA ||
+ Dynamic->d_tag == ELF::DT_JMPREL) {
+ Offsets.push_back(Dynamic->d_un.d_val);
+ }
+ }
+ }
+ for (const Elf_Shdr &Sec : *SectionsOrErr) {
+ if (is_contained(Offsets, Sec.sh_offset))
+ Res.emplace_back(toDRI(&Sec), this);
+ }
+ return Res;
+}
+
+template <class ELFT>
bool ELFObjectFile<ELFT>::isSectionVirtual(DataRefImpl Sec) const {
return getSection(Sec)->sh_type == ELF::SHT_NOBITS;
}
@@ -790,8 +832,6 @@ ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel) const {
template <class ELFT>
uint64_t ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel) const {
- assert(EF.getHeader()->e_type == ELF::ET_REL &&
- "Only relocatable object files have relocation offsets");
const Elf_Shdr *sec = getRelSection(Rel);
if (sec->sh_type == ELF::SHT_REL)
return getRel(Rel)->r_offset;
@@ -986,8 +1026,6 @@ StringRef ELFObjectFile<ELFT>::getFileFormatName() const {
case ELF::EM_SPARC:
case ELF::EM_SPARC32PLUS:
return "ELF32-sparc";
- case ELF::EM_WEBASSEMBLY:
- return "ELF32-wasm";
case ELF::EM_AMDGPU:
return "ELF32-amdgpu";
default:
@@ -1011,8 +1049,6 @@ StringRef ELFObjectFile<ELFT>::getFileFormatName() const {
return "ELF64-sparc";
case ELF::EM_MIPS:
return "ELF64-mips";
- case ELF::EM_WEBASSEMBLY:
- return "ELF64-wasm";
case ELF::EM_AMDGPU:
return "ELF64-amdgpu";
case ELF::EM_BPF:
@@ -1074,26 +1110,20 @@ template <class ELFT> Triple::ArchType ELFObjectFile<ELFT>::getArch() const {
return IsLittleEndian ? Triple::sparcel : Triple::sparc;
case ELF::EM_SPARCV9:
return Triple::sparcv9;
- case ELF::EM_WEBASSEMBLY:
- switch (EF.getHeader()->e_ident[ELF::EI_CLASS]) {
- case ELF::ELFCLASS32: return Triple::wasm32;
- case ELF::ELFCLASS64: return Triple::wasm64;
- default: return Triple::UnknownArch;
- }
case ELF::EM_AMDGPU: {
if (!IsLittleEndian)
return Triple::UnknownArch;
- unsigned EFlags = EF.getHeader()->e_flags;
- switch (EFlags & ELF::EF_AMDGPU_ARCH) {
- case ELF::EF_AMDGPU_ARCH_R600:
+ unsigned MACH = EF.getHeader()->e_flags & ELF::EF_AMDGPU_MACH;
+ if (MACH >= ELF::EF_AMDGPU_MACH_R600_FIRST &&
+ MACH <= ELF::EF_AMDGPU_MACH_R600_LAST)
return Triple::r600;
- case ELF::EF_AMDGPU_ARCH_GCN:
+ if (MACH >= ELF::EF_AMDGPU_MACH_AMDGCN_FIRST &&
+ MACH <= ELF::EF_AMDGPU_MACH_AMDGCN_LAST)
return Triple::amdgcn;
- default:
- return Triple::UnknownArch;
- }
+
+ return Triple::UnknownArch;
}
case ELF::EM_BPF:
@@ -1105,6 +1135,11 @@ template <class ELFT> Triple::ArchType ELFObjectFile<ELFT>::getArch() const {
}
template <class ELFT>
+Expected<uint64_t> ELFObjectFile<ELFT>::getStartAddress() const {
+ return EF.getHeader()->e_entry;
+}
+
+template <class ELFT>
ELFObjectFileBase::elf_symbol_iterator_range
ELFObjectFile<ELFT>::getDynamicSymbolIterators() const {
return make_range(dynamic_symbol_begin(), dynamic_symbol_end());