diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h index e700b62c48c..c40586cffb9 100644 --- a/include/llvm/Object/ELF.h +++ b/include/llvm/Object/ELF.h @@ -357,8 +357,8 @@ public: uintX_t getStringTableIndex() const; ELF::Elf64_Word getExtendedSymbolTableIndex(const Elf_Sym *symb) const; const Elf_Ehdr *getHeader() const { return Header; } - const Elf_Shdr *getSection(const Elf_Sym *symb) const; - const Elf_Shdr *getSection(uint32_t Index) const; + ErrorOr getSection(const Elf_Sym *symb) const; + ErrorOr getSection(uint32_t Index) const; const Elf_Sym *getSymbol(uint32_t index) const; ErrorOr getStaticSymbolName(const Elf_Sym *Symb) const; @@ -465,11 +465,12 @@ ELFFile::getExtendedSymbolTableIndex(const Elf_Sym *symb) const { } template -const typename ELFFile::Elf_Shdr * +ErrorOr::Elf_Shdr *> ELFFile::getSection(const Elf_Sym *symb) const { - if (symb->st_shndx == ELF::SHN_XINDEX) + uint32_t Index = symb->st_shndx; + if (Index == ELF::SHN_XINDEX) return getSection(ExtendedSymbolTable.lookup(symb)); - if (symb->st_shndx >= ELF::SHN_LORESERVE) + if (Index == ELF::SHN_UNDEF || Index >= ELF::SHN_LORESERVE) return nullptr; return getSection(symb->st_shndx); } @@ -532,7 +533,10 @@ std::pair::Elf_Shdr *, ELFFile::getRelocationSymbol(const Elf_Shdr *Sec, const RelT *Rel) const { if (!Sec->sh_link) return std::make_pair(nullptr, nullptr); - const Elf_Shdr *SymTable = getSection(Sec->sh_link); + ErrorOr SymTableOrErr = getSection(Sec->sh_link); + if (std::error_code EC = SymTableOrErr.getError()) + report_fatal_error(EC.message()); + const Elf_Shdr *SymTable = *SymTableOrErr; return std::make_pair( SymTable, getEntry(SymTable, Rel->getSymbol(isMips64EL()))); } @@ -615,7 +619,10 @@ ELFFile::ELFFile(StringRef Object, std::error_code &EC) return; } dot_symtab_sec = &Sec; - ErrorOr SymtabOrErr = getStringTable(getSection(Sec.sh_link)); + ErrorOr SectionOrErr = getSection(Sec.sh_link); + if ((EC = SectionOrErr.getError())) + return; + ErrorOr SymtabOrErr = getStringTable(*SectionOrErr); if ((EC = SymtabOrErr.getError())) return; DotStrtab = *SymtabOrErr; @@ -629,7 +636,10 @@ ELFFile::ELFFile(StringRef Object, std::error_code &EC) DynSymRegion.Addr = base() + Sec.sh_offset; DynSymRegion.Size = Sec.sh_size; DynSymRegion.EntSize = Sec.sh_entsize; - const Elf_Shdr *DynStr = getSection(Sec.sh_link); + ErrorOr DynStrOrErr = getSection(Sec.sh_link); + if ((EC = DynStrOrErr.getError())) + return; + const Elf_Shdr *DynStr = *DynStrOrErr; DynStrRegion.Addr = base() + DynStr->sh_offset; DynStrRegion.Size = DynStr->sh_size; DynStrRegion.EntSize = DynStr->sh_entsize; @@ -673,8 +683,11 @@ ELFFile::ELFFile(StringRef Object, std::error_code &EC) } // Get string table sections. - ErrorOr SymtabOrErr = - getStringTable(getSection(getStringTableIndex())); + ErrorOr StrTabSecOrErr = getSection(getStringTableIndex()); + if ((EC = StrTabSecOrErr.getError())) + return; + + ErrorOr SymtabOrErr = getStringTable(*StrTabSecOrErr); if ((EC = SymtabOrErr.getError())) return; DotShstrtab = *SymtabOrErr; @@ -825,7 +838,10 @@ StringRef ELFFile::getLoadName() const { template template const T *ELFFile::getEntry(uint32_t Section, uint32_t Entry) const { - return getEntry(getSection(Section), Entry); + ErrorOr Sec = getSection(Section); + if (std::error_code EC = Sec.getError()) + report_fatal_error(EC.message()); + return getEntry(*Sec, Entry); } template @@ -837,17 +853,15 @@ const T *ELFFile::getEntry(const Elf_Shdr *Section, } template -const typename ELFFile::Elf_Shdr * -ELFFile::getSection(uint32_t index) const { - if (index == 0) - return nullptr; - if (!SectionHeaderTable || index >= getNumSections()) - // FIXME: Proper error handling. - report_fatal_error("Invalid section index!"); +ErrorOr::Elf_Shdr *> +ELFFile::getSection(uint32_t Index) const { + assert(SectionHeaderTable && "SectionHeaderTable not initialized!"); + if (Index >= getNumSections()) + return object_error::invalid_section_index; return reinterpret_cast( - reinterpret_cast(SectionHeaderTable) - + (index * Header->e_shentsize)); + reinterpret_cast(SectionHeaderTable) + + (Index * Header->e_shentsize)); } template diff --git a/include/llvm/Object/ELFObjectFile.h b/include/llvm/Object/ELFObjectFile.h index f5fc132711c..d10c1f60233 100644 --- a/include/llvm/Object/ELFObjectFile.h +++ b/include/llvm/Object/ELFObjectFile.h @@ -241,7 +241,10 @@ protected: /// \brief Get the relocation section that contains \a Rel. const Elf_Shdr *getRelSection(DataRefImpl Rel) const { - return EF.getSection(Rel.d.a); + ErrorOr Sec = EF.getSection(Rel.d.a); + if (std::error_code EC = Sec.getError()) + report_fatal_error(EC.message()); + return *Sec; } const Elf_Rel *getRel(DataRefImpl Rel) const; @@ -406,8 +409,11 @@ std::error_code ELFObjectFile::getSymbolAddress(DataRefImpl Symb, const Elf_Ehdr *Header = EF.getHeader(); if (Header->e_type == ELF::ET_REL) { - const typename ELFFile::Elf_Shdr * Section = EF.getSection(ESym); - if (Section != nullptr) + ErrorOr SectionOrErr = EF.getSection(ESym); + if (std::error_code EC = SectionOrErr.getError()) + return EC; + const Elf_Shdr *Section = *SectionOrErr; + if (Section) Result += Section->sh_addr; } @@ -511,14 +517,17 @@ uint32_t ELFObjectFile::getSymbolFlags(DataRefImpl Sym) const { template section_iterator ELFObjectFile::getSymbolSection(const Elf_Sym *ESym) const { - const Elf_Shdr *ESec = EF.getSection(ESym); + ErrorOr ESecOrErr = EF.getSection(ESym); + if (std::error_code EC = ESecOrErr.getError()) + report_fatal_error(EC.message()); + + const Elf_Shdr *ESec = *ESecOrErr; if (!ESec) return section_end(); - else { - DataRefImpl Sec; - Sec.p = reinterpret_cast(ESec); - return section_iterator(SectionRef(Sec, this)); - } + + DataRefImpl Sec; + Sec.p = reinterpret_cast(ESec); + return section_iterator(SectionRef(Sec, this)); } template @@ -629,8 +638,10 @@ ELFObjectFile::getRelocatedSection(DataRefImpl Sec) const { if (Type != ELF::SHT_REL && Type != ELF::SHT_RELA) return section_end(); - const Elf_Shdr *R = EF.getSection(EShdr->sh_info); - return section_iterator(SectionRef(toDRI(R), this)); + ErrorOr R = EF.getSection(EShdr->sh_info); + if (std::error_code EC = R.getError()) + report_fatal_error(EC.message()); + return section_iterator(SectionRef(toDRI(*R), this)); } // Relocations @@ -651,7 +662,10 @@ ELFObjectFile::getRelocationSymbol(DataRefImpl Rel) const { if (!symbolIdx) return symbol_end(); - const Elf_Shdr *SymSec = EF.getSection(sec->sh_link); + ErrorOr SymSecOrErr = EF.getSection(sec->sh_link); + if (std::error_code EC = SymSecOrErr.getError()) + report_fatal_error(EC.message()); + const Elf_Shdr *SymSec = *SymSecOrErr; DataRefImpl SymbolData; switch (SymSec->sh_type) { @@ -676,8 +690,11 @@ ELFObjectFile::getRelocationAddress(DataRefImpl Rel) const { if (Header->e_type == ELF::ET_REL) { const Elf_Shdr *RelocationSec = getRelSection(Rel); - const Elf_Shdr *RelocatedSec = EF.getSection(RelocationSec->sh_info); - return ROffset + RelocatedSec->sh_addr; + ErrorOr RelocatedSec = + EF.getSection(RelocationSec->sh_info); + if (std::error_code EC = RelocatedSec.getError()) + return EC; + return ROffset + (*RelocatedSec)->sh_addr; } return ROffset; } diff --git a/include/llvm/Object/Error.h b/include/llvm/Object/Error.h index 1b0b56787c5..aa320bb51a4 100644 --- a/include/llvm/Object/Error.h +++ b/include/llvm/Object/Error.h @@ -28,6 +28,7 @@ enum class object_error { parse_failed, unexpected_eof, string_table_non_null_end, + invalid_section_index, bitcode_section_not_found, macho_small_load_command, macho_load_segment_too_many_sections, diff --git a/lib/Object/Error.cpp b/lib/Object/Error.cpp index 5d613d77609..7ca2f12f092 100644 --- a/lib/Object/Error.cpp +++ b/lib/Object/Error.cpp @@ -43,6 +43,8 @@ std::string _object_error_category::message(int EV) const { return "The end of the file was unexpectedly encountered"; case object_error::string_table_non_null_end: return "String table must end with a null terminator"; + case object_error::invalid_section_index: + return "Invalid section index"; case object_error::bitcode_section_not_found: return "Bitcode section not found in object file"; case object_error::macho_small_load_command: diff --git a/test/Object/invalid.test b/test/Object/invalid.test index 75402631c9f..2f42bde6dc6 100644 --- a/test/Object/invalid.test +++ b/test/Object/invalid.test @@ -40,7 +40,7 @@ INVALID-SYM-SIZE: Invalid symbol size RUN: not llvm-readobj -t %p/Inputs/invalid-section-index.elf 2>&1 | FileCheck --check-prefix=INVALID-SECTION-INDEX %s -INVALID-SECTION-INDEX: Invalid section index! +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 size diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp index dde7e55cfa0..6139cfbea1b 100644 --- a/tools/llvm-objdump/llvm-objdump.cpp +++ b/tools/llvm-objdump/llvm-objdump.cpp @@ -319,12 +319,20 @@ static std::error_code getRelocationValueString(const ELFObjectFile *Obj, typedef typename ELFObjectFile::Elf_Shdr Elf_Shdr; const ELFFile &EF = *Obj->getELFFile(); - const Elf_Shdr *sec = EF.getSection(Rel.d.a); - const Elf_Shdr *SymTab = EF.getSection(sec->sh_link); + ErrorOr SecOrErr = EF.getSection(Rel.d.a); + if (std::error_code EC = SecOrErr.getError()) + return EC; + const Elf_Shdr *Sec = *SecOrErr; + ErrorOr SymTabOrErr = EF.getSection(Sec->sh_link); + if (std::error_code EC = SymTabOrErr.getError()) + return EC; + const Elf_Shdr *SymTab = *SymTabOrErr; assert(SymTab->sh_type == ELF::SHT_SYMTAB || SymTab->sh_type == ELF::SHT_DYNSYM); - const Elf_Shdr *StrTabSec = EF.getSection(SymTab->sh_link); - ErrorOr StrTabOrErr = EF.getStringTable(StrTabSec); + ErrorOr StrTabSec = EF.getSection(SymTab->sh_link); + if (std::error_code EC = StrTabSec.getError()) + return EC; + ErrorOr StrTabOrErr = EF.getStringTable(*StrTabSec); if (std::error_code EC = StrTabOrErr.getError()) return EC; StringRef StrTab = *StrTabOrErr; @@ -332,7 +340,7 @@ static std::error_code getRelocationValueString(const ELFObjectFile *Obj, StringRef res; int64_t addend = 0; uint16_t symbol_index = 0; - switch (sec->sh_type) { + switch (Sec->sh_type) { default: return object_error::parse_failed; case ELF::SHT_REL: { @@ -349,11 +357,13 @@ static std::error_code getRelocationValueString(const ELFObjectFile *Obj, } } const Elf_Sym *symb = - EF.template getEntry(sec->sh_link, symbol_index); + EF.template getEntry(Sec->sh_link, symbol_index); StringRef Target; - const Elf_Shdr *SymSec = EF.getSection(symb); + ErrorOr SymSec = EF.getSection(symb); + if (std::error_code EC = SymSec.getError()) + return EC; if (symb->getType() == ELF::STT_SECTION) { - ErrorOr SecName = EF.getSectionName(SymSec); + ErrorOr SecName = EF.getSectionName(*SymSec); if (std::error_code EC = SecName.getError()) return EC; Target = *SecName; diff --git a/tools/llvm-readobj/ARMEHABIPrinter.h b/tools/llvm-readobj/ARMEHABIPrinter.h index 55d10b151de..dd2490d503d 100644 --- a/tools/llvm-readobj/ARMEHABIPrinter.h +++ b/tools/llvm-readobj/ARMEHABIPrinter.h @@ -377,7 +377,10 @@ PrinterContext::FindExceptionTable(unsigned IndexSectionIndex, std::pair Symbol = ELF->getRelocationSymbol(&Sec, &RelA); - return ELF->getSection(Symbol.second); + ErrorOr Ret = ELF->getSection(Symbol.second); + if (std::error_code EC = Ret.getError()) + report_fatal_error(EC.message()); + return *Ret; } } } diff --git a/tools/llvm-readobj/ELFDumper.cpp b/tools/llvm-readobj/ELFDumper.cpp index 705ab6c62e5..a4b25efeb9b 100644 --- a/tools/llvm-readobj/ELFDumper.cpp +++ b/tools/llvm-readobj/ELFDumper.cpp @@ -162,8 +162,9 @@ getSectionNameIndex(const ELFO &Obj, const typename ELFO::Elf_Sym *Symbol, else { if (SectionIndex == SHN_XINDEX) SectionIndex = Obj.getExtendedSymbolTableIndex(&*Symbol); - const typename ELFO::Elf_Shdr *Sec = Obj.getSection(SectionIndex); - SectionName = errorOrDefault(Obj.getSectionName(Sec)); + ErrorOr Sec = Obj.getSection(SectionIndex); + if (!error(Sec.getError())) + SectionName = errorOrDefault(Obj.getSectionName(*Sec)); } } @@ -644,7 +645,10 @@ void ELFDumper::printSections() { if (opts::SectionSymbols) { ListScope D(W, "Symbols"); for (const typename ELFO::Elf_Sym &Sym : Obj->symbols()) { - if (Obj->getSection(&Sym) == &Sec) + ErrorOr SymSec = Obj->getSection(&Sym); + if (!SymSec) + continue; + if (*SymSec == &Sec) printSymbol(&Sym, false); } } @@ -746,16 +750,20 @@ void ELFDumper::printRelocation(const Elf_Shdr *Sec, std::pair Sym = Obj->getRelocationSymbol(Sec, &Rel); if (Sym.second && Sym.second->getType() == ELF::STT_SECTION) { - const Elf_Shdr *Sec = Obj->getSection(Sym.second); - ErrorOr SecName = Obj->getSectionName(Sec); - if (SecName) - TargetName = SecName.get(); + ErrorOr Sec = Obj->getSection(Sym.second); + if (!error(Sec.getError())) { + ErrorOr SecName = Obj->getSectionName(*Sec); + if (SecName) + TargetName = SecName.get(); + } } else if (Sym.first) { const Elf_Shdr *SymTable = Sym.first; - const Elf_Shdr *StrTableSec = Obj->getSection(SymTable->sh_link); - ErrorOr StrTableOrErr = Obj->getStringTable(StrTableSec); - if (!error(StrTableOrErr.getError())) - TargetName = errorOrDefault(Sym.second->getName(*StrTableOrErr)); + ErrorOr StrTableSec = Obj->getSection(SymTable->sh_link); + if (!error(StrTableSec.getError())) { + ErrorOr StrTableOrErr = Obj->getStringTable(*StrTableSec); + if (!error(StrTableOrErr.getError())) + TargetName = errorOrDefault(Sym.second->getName(*StrTableOrErr)); + } } if (opts::ExpandRelocs) { diff --git a/tools/obj2yaml/elf2yaml.cpp b/tools/obj2yaml/elf2yaml.cpp index db384b05085..9afcedef639 100644 --- a/tools/obj2yaml/elf2yaml.cpp +++ b/tools/obj2yaml/elf2yaml.cpp @@ -157,7 +157,10 @@ std::error_code ELFDumper::dumpSymbol(const Elf_Sym *Sym, bool IsDynamic, return EC; S.Name = NameOrErr.get(); - const Elf_Shdr *Shdr = Obj.getSection(&*Sym); + ErrorOr ShdrOrErr = Obj.getSection(&*Sym); + if (std::error_code EC = ShdrOrErr.getError()) + return EC; + const Elf_Shdr *Shdr = *ShdrOrErr; if (!Shdr) return obj2yaml_error::success; @@ -183,8 +186,10 @@ std::error_code ELFDumper::dumpRelocation(const Elf_Shdr *Shdr, return obj2yaml_error::success; const Elf_Shdr *SymTab = NamePair.first; - const Elf_Shdr *StrTabSec = Obj.getSection(SymTab->sh_link); - ErrorOr StrTabOrErr = Obj.getStringTable(StrTabSec); + ErrorOr StrTabSec = Obj.getSection(SymTab->sh_link); + if (std::error_code EC = StrTabSec.getError()) + return EC; + ErrorOr StrTabOrErr = Obj.getStringTable(*StrTabSec); if (std::error_code EC = StrTabOrErr.getError()) return EC; StringRef StrTab = *StrTabOrErr; @@ -211,12 +216,13 @@ std::error_code ELFDumper::dumpCommonSection(const Elf_Shdr *Shdr, S.Name = NameOrErr.get(); if (Shdr->sh_link != ELF::SHN_UNDEF) { - if (const Elf_Shdr *LinkSection = Obj.getSection(Shdr->sh_link)) { - NameOrErr = Obj.getSectionName(LinkSection); - if (std::error_code EC = NameOrErr.getError()) - return EC; - S.Link = NameOrErr.get(); - } + ErrorOr LinkSection = Obj.getSection(Shdr->sh_link); + if (std::error_code EC = LinkSection.getError()) + return EC; + NameOrErr = Obj.getSectionName(*LinkSection); + if (std::error_code EC = NameOrErr.getError()) + return EC; + S.Link = NameOrErr.get(); } return obj2yaml_error::success; @@ -229,12 +235,14 @@ ELFDumper::dumpCommonRelocationSection(const Elf_Shdr *Shdr, if (std::error_code EC = dumpCommonSection(Shdr, S)) return EC; - if (const Elf_Shdr *InfoSection = Obj.getSection(Shdr->sh_info)) { - ErrorOr NameOrErr = Obj.getSectionName(InfoSection); - if (std::error_code EC = NameOrErr.getError()) - return EC; - S.Info = NameOrErr.get(); - } + ErrorOr InfoSection = Obj.getSection(Shdr->sh_info); + if (std::error_code EC = InfoSection.getError()) + return EC; + + ErrorOr NameOrErr = Obj.getSectionName(*InfoSection); + if (std::error_code EC = NameOrErr.getError()) + return EC; + S.Info = NameOrErr.get(); return obj2yaml_error::success; } @@ -304,9 +312,13 @@ ErrorOr ELFDumper::dumpGroup(const Elf_Shdr *Shdr) { return EC; // Get sh_info which is the signature. const Elf_Sym *symbol = Obj.getSymbol(Shdr->sh_info); - const Elf_Shdr *symtab = Obj.getSection(Shdr->sh_link); - const Elf_Shdr *StrTabSec = Obj.getSection(symtab->sh_link); - ErrorOr StrTabOrErr = Obj.getStringTable(StrTabSec); + ErrorOr Symtab = Obj.getSection(Shdr->sh_link); + if (std::error_code EC = Symtab.getError()) + return EC; + ErrorOr StrTabSec = Obj.getSection((*Symtab)->sh_link); + if (std::error_code EC = StrTabSec.getError()) + return EC; + ErrorOr StrTabOrErr = Obj.getStringTable(*StrTabSec); if (std::error_code EC = StrTabOrErr.getError()) return EC; StringRef StrTab = *StrTabOrErr; @@ -325,8 +337,10 @@ ErrorOr ELFDumper::dumpGroup(const Elf_Shdr *Shdr) { if (groupMembers[i] == llvm::ELF::GRP_COMDAT) { s.sectionNameOrType = "GRP_COMDAT"; } else { - const Elf_Shdr *sHdr = Obj.getSection(groupMembers[i]); - ErrorOr sectionName = Obj.getSectionName(sHdr); + ErrorOr sHdr = Obj.getSection(groupMembers[i]); + if (std::error_code EC = sHdr.getError()) + return EC; + ErrorOr sectionName = Obj.getSectionName(*sHdr); if (std::error_code ec = sectionName.getError()) return ec; s.sectionNameOrType = *sectionName;