From: Rafael Espindola Date: Thu, 6 Oct 2016 14:47:04 +0000 (+0000) Subject: Refactor to use getSectionContentsAsArray. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=42b70df58d531d039ab74ddc71dc9013a2416fc7;p=llvm Refactor to use getSectionContentsAsArray. This centralizes quite a bit of error checking. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@283454 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h index 586f9d643c3..fceb0a19f80 100644 --- a/include/llvm/Object/ELF.h +++ b/include/llvm/Object/ELF.h @@ -115,61 +115,33 @@ public: return makeArrayRef(section_begin(), section_end()); } - const Elf_Sym *symbol_begin(const Elf_Shdr *Sec) const { + Elf_Sym_Range symbols(const Elf_Shdr *Sec) const { if (!Sec) - return nullptr; + return makeArrayRef(nullptr, nullptr); if (Sec->sh_entsize != sizeof(Elf_Sym)) report_fatal_error("Invalid symbol size"); - return reinterpret_cast(base() + Sec->sh_offset); - } - const Elf_Sym *symbol_end(const Elf_Shdr *Sec) const { - if (!Sec) - return nullptr; - uint64_t Size = Sec->sh_size; - if (Size % sizeof(Elf_Sym)) - report_fatal_error("Invalid symbol table size"); - return symbol_begin(Sec) + Size / sizeof(Elf_Sym); - } - Elf_Sym_Range symbols(const Elf_Shdr *Sec) const { - return makeArrayRef(symbol_begin(Sec), symbol_end(Sec)); - } - - const Elf_Rela *rela_begin(const Elf_Shdr *sec) const { - if (sec->sh_entsize != sizeof(Elf_Rela)) - report_fatal_error("Invalid relocation entry size"); - if (sec->sh_offset >= Buf.size()) - report_fatal_error("Invalid relocation entry offset"); - return reinterpret_cast(base() + sec->sh_offset); - } - - const Elf_Rela *rela_end(const Elf_Shdr *sec) const { - uint64_t Size = sec->sh_size; - if (Size % sizeof(Elf_Rela)) - report_fatal_error("Invalid relocation table size"); - return rela_begin(sec) + Size / sizeof(Elf_Rela); + auto V = getSectionContentsAsArray(Sec); + if (!V) + report_fatal_error(V.getError().message()); + return *V; } Elf_Rela_Range relas(const Elf_Shdr *Sec) const { - return makeArrayRef(rela_begin(Sec), rela_end(Sec)); - } - - const Elf_Rel *rel_begin(const Elf_Shdr *sec) const { - if (sec->sh_entsize != sizeof(Elf_Rel)) + if (Sec->sh_entsize != sizeof(Elf_Rela)) report_fatal_error("Invalid relocation entry size"); - if (sec->sh_offset >= Buf.size()) - report_fatal_error("Invalid relocation entry offset"); - return reinterpret_cast(base() + sec->sh_offset); - } - - const Elf_Rel *rel_end(const Elf_Shdr *sec) const { - uint64_t Size = sec->sh_size; - if (Size % sizeof(Elf_Rel)) - report_fatal_error("Invalid relocation table size"); - return rel_begin(sec) + Size / sizeof(Elf_Rel); + auto V = getSectionContentsAsArray(Sec); + if (!V) + report_fatal_error(V.getError().message()); + return *V; } Elf_Rel_Range rels(const Elf_Shdr *Sec) const { - return makeArrayRef(rel_begin(Sec), rel_end(Sec)); + if (Sec->sh_entsize != sizeof(Elf_Rel)) + report_fatal_error("Invalid relocation entry size"); + auto V = getSectionContentsAsArray(Sec); + if (!V) + report_fatal_error(V.getError().message()); + return *V; } /// \brief Iterate over program header table. @@ -202,7 +174,7 @@ public: ErrorOr getSection(uint32_t Index) const; const Elf_Sym *getSymbol(const Elf_Shdr *Sec, uint32_t Index) const { - return &*(symbol_begin(Sec) + Index); + return &symbols(Sec)[Index]; } ErrorOr getSectionName(const Elf_Shdr *Section) const; @@ -220,7 +192,7 @@ template uint32_t ELFFile::getExtendedSymbolTableIndex( const Elf_Sym *Sym, const Elf_Shdr *SymTab, ArrayRef ShndxTable) const { - return getExtendedSymbolTableIndex(Sym, symbol_begin(SymTab), ShndxTable); + return getExtendedSymbolTableIndex(Sym, symbols(SymTab).begin(), ShndxTable); } template @@ -440,29 +412,23 @@ ErrorOr ELFFile::getStringTable(const Elf_Shdr *Section) const { if (Section->sh_type != ELF::SHT_STRTAB) return object_error::parse_failed; - uint64_t Offset = Section->sh_offset; - uint64_t Size = Section->sh_size; - if (Offset + Size > Buf.size()) - return object_error::parse_failed; - StringRef Data((const char *)base() + Section->sh_offset, Size); - if (Data[Size - 1] != '\0') + auto V = getSectionContentsAsArray(Section); + if (std::error_code EC = V.getError()) + return EC; + ArrayRef Data = *V; + if (Data.back() != '\0') return object_error::string_table_non_null_end; - return Data; + return StringRef(Data.begin(), Data.size()); } template ErrorOr::Elf_Word>> ELFFile::getSHNDXTable(const Elf_Shdr &Section) const { assert(Section.sh_type == ELF::SHT_SYMTAB_SHNDX); - const Elf_Word *ShndxTableBegin = - reinterpret_cast(base() + Section.sh_offset); - uintX_t Size = Section.sh_size; - if (Size % sizeof(uint32_t)) - return object_error::parse_failed; - uintX_t NumSymbols = Size / sizeof(uint32_t); - const Elf_Word *ShndxTableEnd = ShndxTableBegin + NumSymbols; - if (reinterpret_cast(ShndxTableEnd) > Buf.end()) - return object_error::parse_failed; + auto VOrErr = getSectionContentsAsArray(&Section); + if (std::error_code EC = VOrErr.getError()) + return EC; + ArrayRef V = *VOrErr; ErrorOr SymTableOrErr = getSection(Section.sh_link); if (std::error_code EC = SymTableOrErr.getError()) return EC; @@ -470,9 +436,9 @@ ELFFile::getSHNDXTable(const Elf_Shdr &Section) const { if (SymTable.sh_type != ELF::SHT_SYMTAB && SymTable.sh_type != ELF::SHT_DYNSYM) return object_error::parse_failed; - if (NumSymbols != (SymTable.sh_size / sizeof(Elf_Sym))) + if (V.size() != (SymTable.sh_size / sizeof(Elf_Sym))) return object_error::parse_failed; - return makeArrayRef(ShndxTableBegin, ShndxTableEnd); + return V; } template diff --git a/include/llvm/Object/ELFObjectFile.h b/include/llvm/Object/ELFObjectFile.h index 07c6364a689..a023d5b3295 100644 --- a/include/llvm/Object/ELFObjectFile.h +++ b/include/llvm/Object/ELFObjectFile.h @@ -496,8 +496,8 @@ uint32_t ELFObjectFile::getSymbolFlags(DataRefImpl Sym) const { 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)) + ESym == EF.symbols(DotSymtabSec).begin() || + ESym == EF.symbols(DotDynSymSec).begin()) Result |= SymbolRef::SF_FormatSpecific; if (EF.getHeader()->e_machine == ELF::EM_ARM) { diff --git a/test/Object/invalid.test b/test/Object/invalid.test index 2d5e0e27440..774aa4776b5 100644 --- a/test/Object/invalid.test +++ b/test/Object/invalid.test @@ -49,7 +49,7 @@ INVALID-SECTION-SIZE: Invalid section header entry size (e_shentsize) in ELF hea RUN: not llvm-readobj -t %p/Inputs/invalid-symbol-table-size.elf 2>&1 | FileCheck --check-prefix=INVALID-SYMTAB-SIZE %s -INVALID-SYMTAB-SIZE: Invalid symbol table size +INVALID-SYMTAB-SIZE: Invalid data was encountered while parsing the file RUN: not llvm-readobj -t %p/Inputs/invalid-xindex-size.elf 2>&1 | FileCheck --check-prefix=INVALID-XINDEX-SIZE %s @@ -63,4 +63,4 @@ RUN: not llvm-readobj -r %p/Inputs/invalid-relocation-sec-sh_offset.elf-i386 2>& RUN: FileCheck --check-prefix=INVALID-RELOC-SH-OFFSET %s RUN: not llvm-readobj -r %p/Inputs/invalid-relocation-sec-sh_offset.elf-x86-64 2>&1 | \ RUN: FileCheck --check-prefix=INVALID-RELOC-SH-OFFSET %s -INVALID-RELOC-SH-OFFSET: Invalid relocation entry offset +INVALID-RELOC-SH-OFFSET: Invalid data was encountered while parsing the file diff --git a/tools/llvm-readobj/ELFDumper.cpp b/tools/llvm-readobj/ELFDumper.cpp index 26acdeeb3f0..318ad2a0abd 100644 --- a/tools/llvm-readobj/ELFDumper.cpp +++ b/tools/llvm-readobj/ELFDumper.cpp @@ -3493,7 +3493,7 @@ template void LLVMStyle::printSections(const ELFO *Obj) { const Elf_Shdr *SymSec = unwrapOrError( Obj->getSection(&Sym, Symtab, this->dumper()->getShndxTable())); if (SymSec == &Sec) - printSymbol(Obj, &Sym, Obj->symbol_begin(Symtab), StrTable, false); + printSymbol(Obj, &Sym, Obj->symbols(Symtab).begin(), StrTable, false); } }