From: Alexey Samsonov Date: Thu, 28 May 2015 20:25:42 +0000 (+0000) Subject: Object, ELF: Use error code instead of calling report_fatal_error() X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=8ecf661ef1f99e5eb315b054de39a701d507d780;p=oota-llvm.git Object, ELF: Use error code instead of calling report_fatal_error() Make createELFObjectFile() return object_error::parse_failed on encountering invalid ELF file, instead of crashing the program. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@238481 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h index ddabf59f309..dc97c5fe7bb 100644 --- a/include/llvm/Object/ELF.h +++ b/include/llvm/Object/ELF.h @@ -318,7 +318,7 @@ public: std::pair getRelocationSymbol(const Elf_Shdr *RelSec, const RelT *Rel) const; - ELFFile(StringRef Object, std::error_code &ec); + ELFFile(StringRef Object, std::error_code &EC); bool isMipsELF64() const { return Header->e_machine == ELF::EM_MIPS && @@ -622,7 +622,7 @@ typename ELFFile::uintX_t ELFFile::getStringTableIndex() const { } template -ELFFile::ELFFile(StringRef Object, std::error_code &ec) +ELFFile::ELFFile(StringRef Object, std::error_code &EC) : Buf(Object), SectionHeaderTable(nullptr), dot_shstrtab_sec(nullptr), dot_strtab_sec(nullptr), dot_symtab_sec(nullptr), SymbolTableSectionHeaderIndex(nullptr), dot_gnu_version_sec(nullptr), @@ -630,9 +630,11 @@ ELFFile::ELFFile(StringRef Object, std::error_code &ec) dt_soname(nullptr) { const uint64_t FileSize = Buf.size(); - if (sizeof(Elf_Ehdr) > FileSize) - // FIXME: Proper error handling. - report_fatal_error("File too short!"); + if (sizeof(Elf_Ehdr) > FileSize) { + // File too short! + EC = object_error::parse_failed; + return; + } Header = reinterpret_cast(base()); @@ -641,40 +643,50 @@ ELFFile::ELFFile(StringRef Object, std::error_code &ec) const uint64_t SectionTableOffset = Header->e_shoff; - if (SectionTableOffset + sizeof(Elf_Shdr) > FileSize) - // FIXME: Proper error handling. - report_fatal_error("Section header table goes past end of file!"); + if (SectionTableOffset + sizeof(Elf_Shdr) > FileSize) { + // Section header table goes past end of file! + EC = object_error::parse_failed; + return; + } // The getNumSections() call below depends on SectionHeaderTable being set. SectionHeaderTable = reinterpret_cast(base() + SectionTableOffset); const uint64_t SectionTableSize = getNumSections() * Header->e_shentsize; - if (SectionTableOffset + SectionTableSize > FileSize) - // FIXME: Proper error handling. - report_fatal_error("Section table goes past end of file!"); + if (SectionTableOffset + SectionTableSize > FileSize) { + // Section table goes past end of file! + EC = object_error::parse_failed; + return; + } // Scan sections for special sections. for (const Elf_Shdr &Sec : sections()) { switch (Sec.sh_type) { case ELF::SHT_SYMTAB_SHNDX: - if (SymbolTableSectionHeaderIndex) - // FIXME: Proper error handling. - report_fatal_error("More than one .symtab_shndx!"); + if (SymbolTableSectionHeaderIndex) { + // More than one .symtab_shndx! + EC = object_error::parse_failed; + return; + } SymbolTableSectionHeaderIndex = &Sec; break; case ELF::SHT_SYMTAB: - if (dot_symtab_sec) - // FIXME: Proper error handling. - report_fatal_error("More than one .symtab!"); + if (dot_symtab_sec) { + // More than one .symtab! + EC = object_error::parse_failed; + return; + } dot_symtab_sec = &Sec; dot_strtab_sec = getSection(Sec.sh_link); break; case ELF::SHT_DYNSYM: { - if (DynSymRegion.Addr) - // FIXME: Proper error handling. - report_fatal_error("More than one .dynsym!"); + if (DynSymRegion.Addr) { + // More than one .dynsym! + EC = object_error::parse_failed; + return; + } DynSymRegion.Addr = base() + Sec.sh_offset; DynSymRegion.Size = Sec.sh_size; DynSymRegion.EntSize = Sec.sh_entsize; @@ -685,29 +697,37 @@ ELFFile::ELFFile(StringRef Object, std::error_code &ec) break; } case ELF::SHT_DYNAMIC: - if (DynamicRegion.Addr) - // FIXME: Proper error handling. - report_fatal_error("More than one .dynamic!"); + if (DynamicRegion.Addr) { + // More than one .dynamic! + EC = object_error::parse_failed; + return; + } DynamicRegion.Addr = base() + Sec.sh_offset; DynamicRegion.Size = Sec.sh_size; DynamicRegion.EntSize = Sec.sh_entsize; break; case ELF::SHT_GNU_versym: - if (dot_gnu_version_sec != nullptr) - // FIXME: Proper error handling. - report_fatal_error("More than one .gnu.version section!"); + if (dot_gnu_version_sec != nullptr) { + // More than one .gnu.version section! + EC = object_error::parse_failed; + return; + } dot_gnu_version_sec = &Sec; break; case ELF::SHT_GNU_verdef: - if (dot_gnu_version_d_sec != nullptr) - // FIXME: Proper error handling. - report_fatal_error("More than one .gnu.version_d section!"); + if (dot_gnu_version_d_sec != nullptr) { + // More than one .gnu.version_d section! + EC = object_error::parse_failed; + return; + } dot_gnu_version_d_sec = &Sec; break; case ELF::SHT_GNU_verneed: - if (dot_gnu_version_r_sec != nullptr) - // FIXME: Proper error handling. - report_fatal_error("More than one .gnu.version_r section!"); + if (dot_gnu_version_r_sec != nullptr) { + // More than one .gnu.version_r section! + EC = object_error::parse_failed; + return; + } dot_gnu_version_r_sec = &Sec; break; } @@ -744,7 +764,7 @@ ELFFile::ELFFile(StringRef Object, std::error_code &ec) } } - ec = std::error_code(); + EC = std::error_code(); } // Get the symbol table index in the symtab section given a symbol diff --git a/test/DebugInfo/Inputs/invalid.elf b/test/DebugInfo/Inputs/invalid.elf new file mode 100644 index 00000000000..23acad80bc9 Binary files /dev/null and b/test/DebugInfo/Inputs/invalid.elf differ diff --git a/test/DebugInfo/dwarfdump-invalid.test b/test/DebugInfo/dwarfdump-invalid.test new file mode 100644 index 00000000000..db77e4ed951 --- /dev/null +++ b/test/DebugInfo/dwarfdump-invalid.test @@ -0,0 +1,4 @@ +; Verify that llvm-dwarfdump doesn't crash on broken input files. + +RUN: llvm-dwarfdump %p/Inputs/invalid.elf +