diff options
| author | Rafael Espindola <rafael.espindola@gmail.com> | 2016-10-06 14:47:04 +0000 |
|---|---|---|
| committer | Rafael Espindola <rafael.espindola@gmail.com> | 2016-10-06 14:47:04 +0000 |
| commit | c3befb2e39dc60d1f1fd6458bf1901be5623cbef (patch) | |
| tree | 6cc14bcfc78d08e4d4895f6ce4f8c039043ce812 | |
| parent | 6bc2990d1661f81e2dd7cc029bcd95fde55b8198 (diff) | |
| download | bcm5719-llvm-c3befb2e39dc60d1f1fd6458bf1901be5623cbef.tar.gz bcm5719-llvm-c3befb2e39dc60d1f1fd6458bf1901be5623cbef.zip | |
Refactor to use getSectionContentsAsArray.
This centralizes quite a bit of error checking.
llvm-svn: 283454
| -rw-r--r-- | llvm/include/llvm/Object/ELF.h | 96 | ||||
| -rw-r--r-- | llvm/include/llvm/Object/ELFObjectFile.h | 4 | ||||
| -rw-r--r-- | llvm/test/Object/invalid.test | 4 | ||||
| -rw-r--r-- | llvm/tools/llvm-readobj/ELFDumper.cpp | 2 |
4 files changed, 36 insertions, 70 deletions
diff --git a/llvm/include/llvm/Object/ELF.h b/llvm/include/llvm/Object/ELF.h index 586f9d643c3..fceb0a19f80 100644 --- a/llvm/include/llvm/Object/ELF.h +++ b/llvm/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<Elf_Sym>(nullptr, nullptr); if (Sec->sh_entsize != sizeof(Elf_Sym)) report_fatal_error("Invalid symbol size"); - return reinterpret_cast<const Elf_Sym *>(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<const Elf_Rela *>(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<Elf_Sym>(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<const Elf_Rel *>(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<Elf_Rela>(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<Elf_Rel>(Sec); + if (!V) + report_fatal_error(V.getError().message()); + return *V; } /// \brief Iterate over program header table. @@ -202,7 +174,7 @@ public: ErrorOr<const Elf_Shdr *> 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<StringRef> getSectionName(const Elf_Shdr *Section) const; @@ -220,7 +192,7 @@ template <class ELFT> uint32_t ELFFile<ELFT>::getExtendedSymbolTableIndex( const Elf_Sym *Sym, const Elf_Shdr *SymTab, ArrayRef<Elf_Word> ShndxTable) const { - return getExtendedSymbolTableIndex(Sym, symbol_begin(SymTab), ShndxTable); + return getExtendedSymbolTableIndex(Sym, symbols(SymTab).begin(), ShndxTable); } template <class ELFT> @@ -440,29 +412,23 @@ ErrorOr<StringRef> ELFFile<ELFT>::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<char>(Section); + if (std::error_code EC = V.getError()) + return EC; + ArrayRef<char> Data = *V; + if (Data.back() != '\0') return object_error::string_table_non_null_end; - return Data; + return StringRef(Data.begin(), Data.size()); } template <class ELFT> ErrorOr<ArrayRef<typename ELFFile<ELFT>::Elf_Word>> ELFFile<ELFT>::getSHNDXTable(const Elf_Shdr &Section) const { assert(Section.sh_type == ELF::SHT_SYMTAB_SHNDX); - const Elf_Word *ShndxTableBegin = - reinterpret_cast<const Elf_Word *>(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<const char *>(ShndxTableEnd) > Buf.end()) - return object_error::parse_failed; + auto VOrErr = getSectionContentsAsArray<Elf_Word>(&Section); + if (std::error_code EC = VOrErr.getError()) + return EC; + ArrayRef<Elf_Word> V = *VOrErr; ErrorOr<const Elf_Shdr *> SymTableOrErr = getSection(Section.sh_link); if (std::error_code EC = SymTableOrErr.getError()) return EC; @@ -470,9 +436,9 @@ ELFFile<ELFT>::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 <class ELFT> diff --git a/llvm/include/llvm/Object/ELFObjectFile.h b/llvm/include/llvm/Object/ELFObjectFile.h index 07c6364a689..a023d5b3295 100644 --- a/llvm/include/llvm/Object/ELFObjectFile.h +++ b/llvm/include/llvm/Object/ELFObjectFile.h @@ -496,8 +496,8 @@ uint32_t ELFObjectFile<ELFT>::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/llvm/test/Object/invalid.test b/llvm/test/Object/invalid.test index 2d5e0e27440..774aa4776b5 100644 --- a/llvm/test/Object/invalid.test +++ b/llvm/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/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index 26acdeeb3f0..318ad2a0abd 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -3493,7 +3493,7 @@ template <class ELFT> void LLVMStyle<ELFT>::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); } } |

