diff options
Diffstat (limited to 'contrib/llvm/include/llvm/Object/ELFObjectFile.h')
-rw-r--r-- | contrib/llvm/include/llvm/Object/ELFObjectFile.h | 160 |
1 files changed, 117 insertions, 43 deletions
diff --git a/contrib/llvm/include/llvm/Object/ELFObjectFile.h b/contrib/llvm/include/llvm/Object/ELFObjectFile.h index 07c6364..69987d4 100644 --- a/contrib/llvm/include/llvm/Object/ELFObjectFile.h +++ b/contrib/llvm/include/llvm/Object/ELFObjectFile.h @@ -59,6 +59,7 @@ protected: virtual uint32_t getSectionType(DataRefImpl Sec) const = 0; virtual uint64_t getSectionFlags(DataRefImpl Sec) const = 0; + virtual uint64_t getSectionOffset(DataRefImpl Sec) const = 0; virtual ErrorOr<int64_t> getRelocationAddend(DataRefImpl Rel) const = 0; @@ -90,6 +91,10 @@ public: uint64_t getFlags() const { return getObject()->getSectionFlags(getRawDataRefImpl()); } + + uint64_t getOffset() const { + return getObject()->getSectionOffset(getRawDataRefImpl()); + } }; class elf_section_iterator : public section_iterator { @@ -245,11 +250,15 @@ protected: uint32_t getSectionType(DataRefImpl Sec) const override; uint64_t getSectionFlags(DataRefImpl Sec) const override; + uint64_t getSectionOffset(DataRefImpl Sec) const override; StringRef getRelocationTypeName(uint32_t Type) const; /// \brief Get the relocation section that contains \a Rel. const Elf_Shdr *getRelSection(DataRefImpl Rel) const { - return *EF.getSection(Rel.d.a); + auto RelSecOrErr = EF.getSection(Rel.d.a); + if (!RelSecOrErr) + report_fatal_error(errorToErrorCode(RelSecOrErr.takeError()).message()); + return *RelSecOrErr; } DataRefImpl toDRI(const Elf_Shdr *SymTable, unsigned SymbolNum) const { @@ -262,7 +271,13 @@ protected: assert(SymTable->sh_type == ELF::SHT_SYMTAB || SymTable->sh_type == ELF::SHT_DYNSYM); - uintptr_t SHT = reinterpret_cast<uintptr_t>(EF.section_begin()); + auto SectionsOrErr = EF.sections(); + if (!SectionsOrErr) { + DRI.d.a = 0; + DRI.d.b = 0; + return DRI; + } + uintptr_t SHT = reinterpret_cast<uintptr_t>((*SectionsOrErr).begin()); unsigned SymTableIndex = (reinterpret_cast<uintptr_t>(SymTable) - SHT) / sizeof(Elf_Shdr); @@ -311,15 +326,18 @@ public: const Elf_Rela *getRela(DataRefImpl Rela) const; const Elf_Sym *getSymbol(DataRefImpl Sym) const { - return EF.template getEntry<Elf_Sym>(Sym.d.a, Sym.d.b); + auto Ret = EF.template getEntry<Elf_Sym>(Sym.d.a, Sym.d.b); + if (!Ret) + report_fatal_error(errorToErrorCode(Ret.takeError()).message()); + return *Ret; } const Elf_Shdr *getSection(DataRefImpl Sec) const { return reinterpret_cast<const Elf_Shdr *>(Sec.p); } - basic_symbol_iterator symbol_begin_impl() const override; - basic_symbol_iterator symbol_end_impl() const override; + basic_symbol_iterator symbol_begin() const override; + basic_symbol_iterator symbol_end() const override; elf_symbol_iterator dynamic_symbol_begin() const; elf_symbol_iterator dynamic_symbol_end() const; @@ -364,10 +382,18 @@ void ELFObjectFile<ELFT>::moveSymbolNext(DataRefImpl &Sym) const { template <class ELFT> Expected<StringRef> ELFObjectFile<ELFT>::getSymbolName(DataRefImpl Sym) const { const Elf_Sym *ESym = getSymbol(Sym); - const Elf_Shdr *SymTableSec = *EF.getSection(Sym.d.a); - const Elf_Shdr *StringTableSec = *EF.getSection(SymTableSec->sh_link); - StringRef SymTable = *EF.getStringTable(StringTableSec); - return ESym->getName(SymTable); + auto SymTabOrErr = EF.getSection(Sym.d.a); + if (!SymTabOrErr) + return SymTabOrErr.takeError(); + const Elf_Shdr *SymTableSec = *SymTabOrErr; + auto StrTabOrErr = EF.getSection(SymTableSec->sh_link); + if (!StrTabOrErr) + return StrTabOrErr.takeError(); + const Elf_Shdr *StringTableSec = *StrTabOrErr; + auto SymStrTabOrErr = EF.getStringTable(StringTableSec); + if (!SymStrTabOrErr) + return SymStrTabOrErr.takeError(); + return ESym->getName(*SymStrTabOrErr); } template <class ELFT> @@ -381,6 +407,11 @@ uint32_t ELFObjectFile<ELFT>::getSectionType(DataRefImpl Sec) const { } template <class ELFT> +uint64_t ELFObjectFile<ELFT>::getSectionOffset(DataRefImpl Sec) const { + return getSection(Sec)->sh_offset; +} + +template <class ELFT> uint64_t ELFObjectFile<ELFT>::getSymbolValueImpl(DataRefImpl Symb) const { const Elf_Sym *ESym = getSymbol(Symb); uint64_t Ret = ESym->st_value; @@ -409,13 +440,15 @@ ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb) const { } const Elf_Ehdr *Header = EF.getHeader(); - const Elf_Shdr *SymTab = *EF.getSection(Symb.d.a); + auto SymTabOrErr = EF.getSection(Symb.d.a); + if (!SymTabOrErr) + return SymTabOrErr.takeError(); + const Elf_Shdr *SymTab = *SymTabOrErr; if (Header->e_type == ELF::ET_REL) { - ErrorOr<const Elf_Shdr *> SectionOrErr = - EF.getSection(ESym, SymTab, ShndxTable); - if (std::error_code EC = SectionOrErr.getError()) - return errorCodeToError(EC); + auto SectionOrErr = EF.getSection(ESym, SymTab, ShndxTable); + if (!SectionOrErr) + return SectionOrErr.takeError(); const Elf_Shdr *Section = *SectionOrErr; if (Section) Result += Section->sh_addr; @@ -495,9 +528,14 @@ uint32_t ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Sym) const { if (ESym->st_shndx == ELF::SHN_ABS) Result |= SymbolRef::SF_Absolute; - if (ESym->getType() == ELF::STT_FILE || ESym->getType() == ELF::STT_SECTION || - ESym == EF.symbol_begin(DotSymtabSec) || - ESym == EF.symbol_begin(DotDynSymSec)) + if (ESym->getType() == ELF::STT_FILE || ESym->getType() == ELF::STT_SECTION) + Result |= SymbolRef::SF_FormatSpecific; + + auto DotSymtabSecSyms = EF.symbols(DotSymtabSec); + if (DotSymtabSecSyms && ESym == (*DotSymtabSecSyms).begin()) + Result |= SymbolRef::SF_FormatSpecific; + auto DotDynSymSecSyms = EF.symbols(DotDynSymSec); + if (DotDynSymSecSyms && ESym == (*DotDynSymSecSyms).begin()) Result |= SymbolRef::SF_FormatSpecific; if (EF.getHeader()->e_machine == ELF::EM_ARM) { @@ -533,9 +571,9 @@ template <class ELFT> Expected<section_iterator> ELFObjectFile<ELFT>::getSymbolSection(const Elf_Sym *ESym, const Elf_Shdr *SymTab) const { - ErrorOr<const Elf_Shdr *> ESecOrErr = EF.getSection(ESym, SymTab, ShndxTable); - if (std::error_code EC = ESecOrErr.getError()) - return errorCodeToError(EC); + auto ESecOrErr = EF.getSection(ESym, SymTab, ShndxTable); + if (!ESecOrErr) + return ESecOrErr.takeError(); const Elf_Shdr *ESec = *ESecOrErr; if (!ESec) @@ -550,7 +588,10 @@ template <class ELFT> Expected<section_iterator> ELFObjectFile<ELFT>::getSymbolSection(DataRefImpl Symb) const { const Elf_Sym *Sym = getSymbol(Symb); - const Elf_Shdr *SymTab = *EF.getSection(Symb.d.a); + auto SymTabOrErr = EF.getSection(Symb.d.a); + if (!SymTabOrErr) + return SymTabOrErr.takeError(); + const Elf_Shdr *SymTab = *SymTabOrErr; return getSymbolSection(Sym, SymTab); } @@ -563,9 +604,9 @@ void ELFObjectFile<ELFT>::moveSectionNext(DataRefImpl &Sec) const { template <class ELFT> std::error_code ELFObjectFile<ELFT>::getSectionName(DataRefImpl Sec, StringRef &Result) const { - ErrorOr<StringRef> Name = EF.getSectionName(&*getSection(Sec)); + auto Name = EF.getSectionName(&*getSection(Sec)); if (!Name) - return Name.getError(); + return errorToErrorCode(Name.takeError()); Result = *Name; return std::error_code(); } @@ -627,7 +668,10 @@ template <class ELFT> relocation_iterator ELFObjectFile<ELFT>::section_rel_begin(DataRefImpl Sec) const { DataRefImpl RelData; - uintptr_t SHT = reinterpret_cast<uintptr_t>(EF.section_begin()); + auto SectionsOrErr = EF.sections(); + if (!SectionsOrErr) + return relocation_iterator(RelocationRef()); + uintptr_t SHT = reinterpret_cast<uintptr_t>((*SectionsOrErr).begin()); RelData.d.a = (Sec.p - SHT) / EF.getHeader()->e_shentsize; RelData.d.b = 0; return relocation_iterator(RelocationRef(RelData, this)); @@ -644,9 +688,9 @@ ELFObjectFile<ELFT>::section_rel_end(DataRefImpl Sec) const { const Elf_Shdr *RelSec = getRelSection(RelData); // Error check sh_link here so that getRelocationSymbol can just use it. - ErrorOr<const Elf_Shdr *> SymSecOrErr = EF.getSection(RelSec->sh_link); - if (std::error_code EC = SymSecOrErr.getError()) - report_fatal_error(EC.message()); + auto SymSecOrErr = EF.getSection(RelSec->sh_link); + if (!SymSecOrErr) + report_fatal_error(errorToErrorCode(SymSecOrErr.takeError()).message()); RelData.d.b += S->sh_size / S->sh_entsize; return relocation_iterator(RelocationRef(RelData, this)); @@ -663,9 +707,9 @@ ELFObjectFile<ELFT>::getRelocatedSection(DataRefImpl Sec) const { if (Type != ELF::SHT_REL && Type != ELF::SHT_RELA) return section_end(); - ErrorOr<const Elf_Shdr *> R = EF.getSection(EShdr->sh_info); - if (std::error_code EC = R.getError()) - report_fatal_error(EC.message()); + auto R = EF.getSection(EShdr->sh_info); + if (!R) + report_fatal_error(errorToErrorCode(R.takeError()).message()); return section_iterator(SectionRef(toDRI(*R), this)); } @@ -738,14 +782,20 @@ template <class ELFT> const typename ELFObjectFile<ELFT>::Elf_Rel * ELFObjectFile<ELFT>::getRel(DataRefImpl Rel) const { assert(getRelSection(Rel)->sh_type == ELF::SHT_REL); - return EF.template getEntry<Elf_Rel>(Rel.d.a, Rel.d.b); + auto Ret = EF.template getEntry<Elf_Rel>(Rel.d.a, Rel.d.b); + if (!Ret) + report_fatal_error(errorToErrorCode(Ret.takeError()).message()); + return *Ret; } template <class ELFT> const typename ELFObjectFile<ELFT>::Elf_Rela * ELFObjectFile<ELFT>::getRela(DataRefImpl Rela) const { assert(getRelSection(Rela)->sh_type == ELF::SHT_RELA); - return EF.template getEntry<Elf_Rela>(Rela.d.a, Rela.d.b); + auto Ret = EF.template getEntry<Elf_Rela>(Rela.d.a, Rela.d.b); + if (!Ret) + report_fatal_error(errorToErrorCode(Ret.takeError()).message()); + return *Ret; } template <class ELFT> @@ -753,10 +803,13 @@ ELFObjectFile<ELFT>::ELFObjectFile(MemoryBufferRef Object, std::error_code &EC) : ELFObjectFileBase( getELFType(ELFT::TargetEndianness == support::little, ELFT::Is64Bits), Object), - EF(Data.getBuffer(), EC) { - if (EC) + EF(Data.getBuffer()) { + auto SectionsOrErr = EF.sections(); + if (!SectionsOrErr) { + EC = errorToErrorCode(SectionsOrErr.takeError()); return; - for (const Elf_Shdr &Sec : EF.sections()) { + } + for (const Elf_Shdr &Sec : *SectionsOrErr) { switch (Sec.sh_type) { case ELF::SHT_DYNSYM: { if (DotDynSymSec) { @@ -777,9 +830,11 @@ ELFObjectFile<ELFT>::ELFObjectFile(MemoryBufferRef Object, std::error_code &EC) break; } case ELF::SHT_SYMTAB_SHNDX: { - ErrorOr<ArrayRef<Elf_Word>> TableOrErr = EF.getSHNDXTable(Sec); - if ((EC = TableOrErr.getError())) + auto TableOrErr = EF.getSHNDXTable(Sec); + if (!TableOrErr) { + EC = errorToErrorCode(TableOrErr.takeError()); return; + } ShndxTable = *TableOrErr; break; } @@ -788,16 +843,16 @@ ELFObjectFile<ELFT>::ELFObjectFile(MemoryBufferRef Object, std::error_code &EC) } template <class ELFT> -basic_symbol_iterator ELFObjectFile<ELFT>::symbol_begin_impl() const { +basic_symbol_iterator ELFObjectFile<ELFT>::symbol_begin() const { DataRefImpl Sym = toDRI(DotSymtabSec, 0); return basic_symbol_iterator(SymbolRef(Sym, this)); } template <class ELFT> -basic_symbol_iterator ELFObjectFile<ELFT>::symbol_end_impl() const { +basic_symbol_iterator ELFObjectFile<ELFT>::symbol_end() const { const Elf_Shdr *SymTab = DotSymtabSec; if (!SymTab) - return symbol_begin_impl(); + return symbol_begin(); DataRefImpl Sym = toDRI(SymTab, SymTab->sh_size / sizeof(Elf_Sym)); return basic_symbol_iterator(SymbolRef(Sym, this)); } @@ -817,12 +872,18 @@ elf_symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_end() const { template <class ELFT> section_iterator ELFObjectFile<ELFT>::section_begin() const { - return section_iterator(SectionRef(toDRI(EF.section_begin()), this)); + auto SectionsOrErr = EF.sections(); + if (!SectionsOrErr) + return section_iterator(SectionRef()); + return section_iterator(SectionRef(toDRI((*SectionsOrErr).begin()), this)); } template <class ELFT> section_iterator ELFObjectFile<ELFT>::section_end() const { - return section_iterator(SectionRef(toDRI(EF.section_end()), this)); + auto SectionsOrErr = EF.sections(); + if (!SectionsOrErr) + return section_iterator(SectionRef()); + return section_iterator(SectionRef(toDRI((*SectionsOrErr).end()), this)); } template <class ELFT> @@ -854,6 +915,8 @@ StringRef ELFObjectFile<ELFT>::getFileFormatName() const { return "ELF32-mips"; case ELF::EM_PPC: return "ELF32-ppc"; + case ELF::EM_RISCV: + return "ELF32-riscv"; case ELF::EM_SPARC: case ELF::EM_SPARC32PLUS: return "ELF32-sparc"; @@ -874,6 +937,8 @@ StringRef ELFObjectFile<ELFT>::getFileFormatName() const { return (IsLittleEndian ? "ELF64-aarch64-little" : "ELF64-aarch64-big"); case ELF::EM_PPC64: return "ELF64-ppc64"; + case ELF::EM_RISCV: + return "ELF64-riscv"; case ELF::EM_S390: return "ELF64-s390"; case ELF::EM_SPARCV9: @@ -907,7 +972,7 @@ unsigned ELFObjectFile<ELFT>::getArch() const { case ELF::EM_X86_64: return Triple::x86_64; case ELF::EM_AARCH64: - return Triple::aarch64; + return IsLittleEndian ? Triple::aarch64 : Triple::aarch64_be; case ELF::EM_ARM: return Triple::arm; case ELF::EM_AVR: @@ -929,6 +994,15 @@ unsigned ELFObjectFile<ELFT>::getArch() const { return Triple::ppc; case ELF::EM_PPC64: return IsLittleEndian ? Triple::ppc64le : Triple::ppc64; + case ELF::EM_RISCV: + switch (EF.getHeader()->e_ident[ELF::EI_CLASS]) { + case ELF::ELFCLASS32: + return Triple::riscv32; + case ELF::ELFCLASS64: + return Triple::riscv64; + default: + report_fatal_error("Invalid ELFCLASS!"); + } case ELF::EM_S390: return Triple::systemz; |