From: Rafael Espindola Date: Thu, 3 Nov 2016 20:16:53 +0000 (+0000) Subject: Don't error in the ELFFile constructor. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6a445561f960dcd533be8c0e5616cab0ff2f8d49;p=llvm Don't error in the ELFFile constructor. All error checking now happens when the information is needed. The only thing left is the minimum size of the buffer and that can be just a precondition. I will add an ErrorOr create method in a followup commit. Also don't store a pointer to the Header, since it is just a trivial cast. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@285961 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h index 8b5c12b0a74..595657e58e5 100644 --- a/include/llvm/Object/ELF.h +++ b/include/llvm/Object/ELF.h @@ -69,9 +69,11 @@ private: StringRef Buf; - const Elf_Ehdr *Header; - public: + const Elf_Ehdr *getHeader() const { + return reinterpret_cast(base()); + } + template ErrorOr getEntry(uint32_t Section, uint32_t Entry) const; template @@ -96,17 +98,17 @@ public: ErrorOr getRelocationSymbol(const Elf_Rel *Rel, const Elf_Shdr *SymTab) const; - ELFFile(StringRef Object, std::error_code &EC); + ELFFile(StringRef Object); bool isMipsELF64() const { - return Header->e_machine == ELF::EM_MIPS && - Header->getFileClass() == ELF::ELFCLASS64; + return getHeader()->e_machine == ELF::EM_MIPS && + getHeader()->getFileClass() == ELF::ELFCLASS64; } bool isMips64EL() const { - return Header->e_machine == ELF::EM_MIPS && - Header->getFileClass() == ELF::ELFCLASS64 && - Header->getDataEncoding() == ELF::ELFDATA2LSB; + return getHeader()->e_machine == ELF::EM_MIPS && + getHeader()->getFileClass() == ELF::ELFCLASS64 && + getHeader()->getDataEncoding() == ELF::ELFDATA2LSB; } ErrorOr sections() const; @@ -127,14 +129,14 @@ public: /// \brief Iterate over program header table. ErrorOr program_headers() const { - if (Header->e_phnum && Header->e_phentsize != sizeof(Elf_Phdr)) + if (getHeader()->e_phnum && getHeader()->e_phentsize != sizeof(Elf_Phdr)) return object_error::parse_failed; - auto *Begin = reinterpret_cast(base() + Header->e_phoff); - return makeArrayRef(Begin, Begin+Header->e_phnum); + auto *Begin = + reinterpret_cast(base() + getHeader()->e_phoff); + return makeArrayRef(Begin, Begin + getHeader()->e_phnum); } ErrorOr getSectionStringTable(Elf_Shdr_Range Sections) const; - const Elf_Ehdr *getHeader() const { return Header; } ErrorOr getSectionIndex(const Elf_Sym *Sym, Elf_Sym_Range Syms, ArrayRef ShndxTable) const; ErrorOr getSection(const Elf_Sym *Sym, @@ -269,7 +271,7 @@ ELFFile::getSectionContents(const Elf_Shdr *Sec) const { template StringRef ELFFile::getRelocationTypeName(uint32_t Type) const { - return getELFRelocationTypeName(Header->e_machine, Type); + return getELFRelocationTypeName(getHeader()->e_machine, Type); } template @@ -316,7 +318,7 @@ ELFFile::getRelocationSymbol(const Elf_Rel *Rel, template ErrorOr ELFFile::getSectionStringTable(Elf_Shdr_Range Sections) const { - uint32_t Index = Header->e_shstrndx; + uint32_t Index = getHeader()->e_shstrndx; if (Index == ELF::SHN_XINDEX) Index = Sections[0].sh_link; @@ -328,26 +330,8 @@ ELFFile::getSectionStringTable(Elf_Shdr_Range Sections) const { } template -ELFFile::ELFFile(StringRef Object, std::error_code &EC) : Buf(Object) { - const uint64_t FileSize = Buf.size(); - - if (sizeof(Elf_Ehdr) > FileSize) { - // File too short! - EC = object_error::parse_failed; - return; - } - - Header = reinterpret_cast(base()); - - if (Header->e_shoff == 0) { - if (Header->e_shnum != 0) { - // e_shnum should be zero if a file has no section header table - EC = object_error::parse_failed; - } - return; - } - - EC = std::error_code(); +ELFFile::ELFFile(StringRef Object) : Buf(Object) { + assert(sizeof(Elf_Ehdr) <= Buf.size() && "Invalid buffer"); } template @@ -357,12 +341,12 @@ static bool compareAddr(uint64_t VAddr, const Elf_Phdr_Impl *Phdr) { template ErrorOr ELFFile::sections() const { - const uintX_t SectionTableOffset = Header->e_shoff; + const uintX_t SectionTableOffset = getHeader()->e_shoff; if (SectionTableOffset == 0) return ArrayRef(); // Invalid section header entry size (e_shentsize) in ELF header - if (Header->e_shentsize != sizeof(Elf_Shdr)) + if (getHeader()->e_shentsize != sizeof(Elf_Shdr)) return object_error::parse_failed; const uint64_t FileSize = Buf.size(); @@ -378,7 +362,7 @@ ErrorOr ELFFile::sections() const { const Elf_Shdr *First = reinterpret_cast(base() + SectionTableOffset); - uintX_t NumSections = Header->e_shnum; + uintX_t NumSections = getHeader()->e_shnum; if (NumSections == 0) NumSections = First->sh_size; diff --git a/include/llvm/Object/ELFObjectFile.h b/include/llvm/Object/ELFObjectFile.h index f7e9cb9a89f..2a23210e092 100644 --- a/include/llvm/Object/ELFObjectFile.h +++ b/include/llvm/Object/ELFObjectFile.h @@ -773,9 +773,7 @@ ELFObjectFile::ELFObjectFile(MemoryBufferRef Object, std::error_code &EC) : ELFObjectFileBase( getELFType(ELFT::TargetEndianness == support::little, ELFT::Is64Bits), Object), - EF(Data.getBuffer(), EC) { - if (EC) - return; + EF(Data.getBuffer()) { auto SectionsOrErr = EF.sections(); if ((EC = SectionsOrErr.getError())) return;