diff --git a/llvm/include/llvm/Object/ELF.h b/llvm/include/llvm/Object/ELF.h index a2302754bd42..11239061bc65 100644 --- a/llvm/include/llvm/Object/ELF.h +++ b/llvm/include/llvm/Object/ELF.h @@ -107,11 +107,7 @@ public: Header->getDataEncoding() == ELF::ELFDATA2LSB; } - const Elf_Shdr *section_begin() const; - const Elf_Shdr *section_end() const; - Elf_Shdr_Range sections() const { - return makeArrayRef(section_begin(), section_end()); - } + ErrorOr sections() const; Elf_Sym_Range symbols(const Elf_Shdr *Sec) const { if (!Sec) @@ -378,16 +374,12 @@ static bool compareAddr(uint64_t VAddr, const Elf_Phdr_Impl *Phdr) { } template -const typename ELFFile::Elf_Shdr *ELFFile::section_begin() const { +ErrorOr ELFFile::sections() const { + // Invalid section header entry size (e_shentsize) in ELF header if (Header->e_shentsize != sizeof(Elf_Shdr)) - report_fatal_error( - "Invalid section header entry size (e_shentsize) in ELF header"); - return reinterpret_cast(base() + Header->e_shoff); -} - -template -const typename ELFFile::Elf_Shdr *ELFFile::section_end() const { - return section_begin() + getNumSections(); + return object_error::parse_failed; + auto *Begin = reinterpret_cast(base() + Header->e_shoff); + return makeArrayRef(Begin, Begin + getNumSections()); } template diff --git a/llvm/include/llvm/Object/ELFObjectFile.h b/llvm/include/llvm/Object/ELFObjectFile.h index 7d73b19b36d3..179f07a76cc3 100644 --- a/llvm/include/llvm/Object/ELFObjectFile.h +++ b/llvm/include/llvm/Object/ELFObjectFile.h @@ -268,7 +268,7 @@ protected: assert(SymTable->sh_type == ELF::SHT_SYMTAB || SymTable->sh_type == ELF::SHT_DYNSYM); - uintptr_t SHT = reinterpret_cast(EF.section_begin()); + uintptr_t SHT = reinterpret_cast((*EF.sections()).begin()); unsigned SymTableIndex = (reinterpret_cast(SymTable) - SHT) / sizeof(Elf_Shdr); @@ -638,7 +638,7 @@ template relocation_iterator ELFObjectFile::section_rel_begin(DataRefImpl Sec) const { DataRefImpl RelData; - uintptr_t SHT = reinterpret_cast(EF.section_begin()); + uintptr_t SHT = reinterpret_cast((*EF.sections()).begin()); RelData.d.a = (Sec.p - SHT) / EF.getHeader()->e_shentsize; RelData.d.b = 0; return relocation_iterator(RelocationRef(RelData, this)); @@ -767,7 +767,10 @@ ELFObjectFile::ELFObjectFile(MemoryBufferRef Object, std::error_code &EC) EF(Data.getBuffer(), EC) { if (EC) return; - for (const Elf_Shdr &Sec : EF.sections()) { + auto SectionsOrErr = EF.sections(); + if ((EC = SectionsOrErr.getError())) + return; + for (const Elf_Shdr &Sec : *SectionsOrErr) { switch (Sec.sh_type) { case ELF::SHT_DYNSYM: { if (DotDynSymSec) { @@ -828,12 +831,12 @@ elf_symbol_iterator ELFObjectFile::dynamic_symbol_end() const { template section_iterator ELFObjectFile::section_begin() const { - return section_iterator(SectionRef(toDRI(EF.section_begin()), this)); + return section_iterator(SectionRef(toDRI((*EF.sections()).begin()), this)); } template section_iterator ELFObjectFile::section_end() const { - return section_iterator(SectionRef(toDRI(EF.section_end()), this)); + return section_iterator(SectionRef(toDRI((*EF.sections()).end()), this)); } template diff --git a/llvm/test/Object/invalid.test b/llvm/test/Object/invalid.test index da30c64ea44b..43fccccdc06b 100644 --- a/llvm/test/Object/invalid.test +++ b/llvm/test/Object/invalid.test @@ -45,7 +45,7 @@ RUN: not llvm-readobj -t %p/Inputs/invalid-section-index.elf 2>&1 | FileCheck -- INVALID-SECTION-INDEX: Invalid section index RUN: not llvm-readobj -s %p/Inputs/invalid-section-size.elf 2>&1 | FileCheck --check-prefix=INVALID-SECTION-SIZE %s -INVALID-SECTION-SIZE: Invalid section header entry size (e_shentsize) in ELF header +INVALID-SECTION-SIZE: Invalid data was encountered while parsing the file RUN: not llvm-readobj -t %p/Inputs/invalid-symbol-table-size.elf 2>&1 | FileCheck --check-prefix=INVALID-SYMTAB-SIZE %s diff --git a/llvm/tools/llvm-readobj/ARMEHABIPrinter.h b/llvm/tools/llvm-readobj/ARMEHABIPrinter.h index 59c9b713d85e..a85f987def0c 100644 --- a/llvm/tools/llvm-readobj/ARMEHABIPrinter.h +++ b/llvm/tools/llvm-readobj/ARMEHABIPrinter.h @@ -379,7 +379,7 @@ PrinterContext::FindExceptionTable(unsigned IndexSectionIndex, /// handling table. Use this symbol to recover the actual exception handling /// table. - for (const Elf_Shdr &Sec : ELF->sections()) { + for (const Elf_Shdr &Sec : unwrapOrError(ELF->sections())) { if (Sec.sh_type != ELF::SHT_REL || Sec.sh_info != IndexSectionIndex) continue; @@ -548,7 +548,7 @@ void PrinterContext::PrintUnwindInformation() const { DictScope UI(SW, "UnwindInformation"); int SectionIndex = 0; - for (const Elf_Shdr &Sec : ELF->sections()) { + for (const Elf_Shdr &Sec : unwrapOrError(ELF->sections())) { if (Sec.sh_type == ELF::SHT_ARM_EXIDX) { DictScope UIT(SW, "UnwindIndexTable"); diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index 41f06d42a255..845abf9b5fe8 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -728,7 +728,7 @@ getSectionNameIndex(const ELFO &Obj, const typename ELFO::Elf_Sym *Symbol, template static const typename ELFO::Elf_Shdr * findNotEmptySectionByAddress(const ELFO *Obj, uint64_t Addr) { - for (const auto &Shdr : Obj->sections()) + for (const auto &Shdr : unwrapOrError(Obj->sections())) if (Shdr.sh_addr == Addr && Shdr.sh_size > 0) return &Shdr; return nullptr; @@ -737,7 +737,7 @@ findNotEmptySectionByAddress(const ELFO *Obj, uint64_t Addr) { template static const typename ELFO::Elf_Shdr *findSectionByName(const ELFO &Obj, StringRef Name) { - for (const auto &Shdr : Obj.sections()) { + for (const auto &Shdr : unwrapOrError(Obj.sections())) { if (Name == unwrapOrError(Obj.getSectionName(&Shdr))) return &Shdr; } @@ -1315,7 +1315,7 @@ ELFDumper::ELFDumper(const ELFFile *Obj, ScopedPrinter &Writer) LoadSegments.push_back(&Phdr); } - for (const Elf_Shdr &Sec : Obj->sections()) { + for (const Elf_Shdr &Sec : unwrapOrError(Obj->sections())) { switch (Sec.sh_type) { case ELF::SHT_SYMTAB: if (DotSymtabSec != nullptr) @@ -1857,7 +1857,7 @@ template <> void ELFDumper>::printAttributes() { } DictScope BA(W, "BuildAttributes"); - for (const ELFO::Elf_Shdr &Sec : Obj->sections()) { + for (const ELFO::Elf_Shdr &Sec : unwrapOrError(Obj->sections())) { if (Sec.sh_type != ELF::SHT_ARM_ATTRIBUTES) continue; @@ -2336,7 +2336,7 @@ template void ELFDumper::printMipsOptions() { template void ELFDumper::printStackMap() const { const Elf_Shdr *StackMapSection = nullptr; - for (const auto &Sec : Obj->sections()) { + for (const auto &Sec : unwrapOrError(Obj->sections())) { StringRef Name = unwrapOrError(Obj->getSectionName(&Sec)); if (Name == ".llvm_stackmaps") { StackMapSection = &Sec; @@ -2423,7 +2423,7 @@ template void GNUStyle::printFileHeaders(const ELFO *Obj) { template void GNUStyle::printGroupSections(const ELFO *Obj) { uint32_t SectionIndex = 0; bool HasGroups = false; - for (const Elf_Shdr &Sec : Obj->sections()) { + for (const Elf_Shdr &Sec : unwrapOrError(Obj->sections())) { if (Sec.sh_type == ELF::SHT_GROUP) { HasGroups = true; const Elf_Shdr *Symtab = unwrapOrError(Obj->getSection(Sec.sh_link)); @@ -2517,7 +2517,7 @@ static inline void printRelocHeader(raw_ostream &OS, bool Is64, bool IsRela) { template void GNUStyle::printRelocations(const ELFO *Obj) { bool HasRelocSections = false; - for (const Elf_Shdr &Sec : Obj->sections()) { + for (const Elf_Shdr &Sec : unwrapOrError(Obj->sections())) { if (Sec.sh_type != ELF::SHT_REL && Sec.sh_type != ELF::SHT_RELA) continue; HasRelocSections = true; @@ -2663,7 +2663,7 @@ template void GNUStyle::printSections(const ELFO *Obj) { printField(f); OS << "\n"; - for (const Elf_Shdr &Sec : Obj->sections()) { + for (const Elf_Shdr &Sec : unwrapOrError(Obj->sections())) { Number = to_string(SectionIndex); Fields[0].Str = Number; Fields[1].Str = unwrapOrError(Obj->getSectionName(&Sec)); @@ -2941,7 +2941,7 @@ void GNUStyle::printProgramHeaders(const ELFO *Obj) { for (const Elf_Phdr &Phdr : Obj->program_headers()) { std::string Sections; OS << format(" %2.2d ", Phnum++); - for (const Elf_Shdr &Sec : Obj->sections()) { + for (const Elf_Shdr &Sec : unwrapOrError(Obj->sections())) { // Check if each section is in a segment and then print mapping. // readelf additionally makes sure it does not print zero sized sections // at end of segments and for PT_DYNAMIC both start and end of section @@ -3273,7 +3273,7 @@ void GNUStyle::printNotes(const ELFFile *Obj) { if (P.p_type == PT_NOTE) process(P.p_offset, P.p_filesz); } else { - for (const auto &S : Obj->sections()) + for (const auto &S : unwrapOrError(Obj->sections())) if (S.sh_type == SHT_NOTE) process(S.sh_offset, S.sh_size); } @@ -3328,7 +3328,7 @@ void LLVMStyle::printGroupSections(const ELFO *Obj) { DictScope Lists(W, "Groups"); uint32_t SectionIndex = 0; bool HasGroups = false; - for (const Elf_Shdr &Sec : Obj->sections()) { + for (const Elf_Shdr &Sec : unwrapOrError(Obj->sections())) { if (Sec.sh_type == ELF::SHT_GROUP) { HasGroups = true; const Elf_Shdr *Symtab = unwrapOrError(Obj->getSection(Sec.sh_link)); @@ -3362,7 +3362,7 @@ template void LLVMStyle::printRelocations(const ELFO *Obj) { ListScope D(W, "Relocations"); int SectionNumber = -1; - for (const Elf_Shdr &Sec : Obj->sections()) { + for (const Elf_Shdr &Sec : unwrapOrError(Obj->sections())) { ++SectionNumber; if (Sec.sh_type != ELF::SHT_REL && Sec.sh_type != ELF::SHT_RELA) @@ -3436,7 +3436,7 @@ template void LLVMStyle::printSections(const ELFO *Obj) { ListScope SectionsD(W, "Sections"); int SectionIndex = -1; - for (const Elf_Shdr &Sec : Obj->sections()) { + for (const Elf_Shdr &Sec : unwrapOrError(Obj->sections())) { ++SectionIndex; StringRef Name = unwrapOrError(Obj->getSectionName(&Sec)); diff --git a/llvm/tools/obj2yaml/elf2yaml.cpp b/llvm/tools/obj2yaml/elf2yaml.cpp index a079dc21a7f7..d736d8a834f8 100644 --- a/llvm/tools/obj2yaml/elf2yaml.cpp +++ b/llvm/tools/obj2yaml/elf2yaml.cpp @@ -74,7 +74,10 @@ ErrorOr ELFDumper::dump() { const Elf_Shdr *Symtab = nullptr; // Dump sections - for (const Elf_Shdr &Sec : Obj.sections()) { + auto SectionsOrErr = Obj.sections(); + if (std::error_code EC = SectionsOrErr.getError()) + return EC; + for (const Elf_Shdr &Sec : *SectionsOrErr) { switch (Sec.sh_type) { case ELF::SHT_NULL: case ELF::SHT_DYNSYM: