From: Rafael Espindola Date: Mon, 20 Jul 2015 13:35:33 +0000 (+0000) Subject: Simplify iterating over program headers and detect corrupt ones. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=9a4133e1eeab492cca252438bd81bb7a145bf7ed;p=oota-llvm.git Simplify iterating over program headers and detect corrupt ones. We now use a simple pointer and have range loops. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@242669 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h index cc271851e6b..160b12d607e 100644 --- a/include/llvm/Object/ELF.h +++ b/include/llvm/Object/ELF.h @@ -349,18 +349,20 @@ public: } /// \brief Iterate over program header table. - typedef ELFEntityIterator Elf_Phdr_Iter; + const Elf_Phdr *program_header_begin() const { + if (Header->e_phnum && Header->e_phentsize != sizeof(Elf_Phdr)) + report_fatal_error("Invalid program header size"); + return reinterpret_cast(base() + Header->e_phoff); + } - Elf_Phdr_Iter program_header_begin() const { - return Elf_Phdr_Iter(Header->e_phentsize, - (const char*)base() + Header->e_phoff); + const Elf_Phdr *program_header_end() const { + return program_header_begin() + Header->e_phnum; } - Elf_Phdr_Iter program_header_end() const { - return Elf_Phdr_Iter(Header->e_phentsize, - (const char*)base() + - Header->e_phoff + - (Header->e_phnum * Header->e_phentsize)); + typedef iterator_range Elf_Phdr_Range; + + const Elf_Phdr_Range program_headers() const { + return make_range(program_header_begin(), program_header_end()); } uint64_t getNumSections() const; @@ -735,21 +737,16 @@ void ELFFile::scanDynamicTable() { // stack doesn't get realigned despite LoadMap having alignment 8 (PR24113). std::unique_ptr LoadMap(new LoadMapT(Alloc)); - for (Elf_Phdr_Iter PhdrI = program_header_begin(), - PhdrE = program_header_end(); - PhdrI != PhdrE; ++PhdrI) { - if (PhdrI->p_type == ELF::PT_DYNAMIC) { - DynamicRegion.Addr = base() + PhdrI->p_offset; - DynamicRegion.Size = PhdrI->p_filesz; + for (const Elf_Phdr &Phdr : program_headers()) { + if (Phdr.p_type == ELF::PT_DYNAMIC) { + DynamicRegion.Addr = base() + Phdr.p_offset; + DynamicRegion.Size = Phdr.p_filesz; DynamicRegion.EntSize = sizeof(Elf_Dyn); continue; } - if (PhdrI->p_type != ELF::PT_LOAD) - continue; - if (PhdrI->p_filesz == 0) + if (Phdr.p_type != ELF::PT_LOAD || Phdr.p_filesz == 0) continue; - LoadMap->insert(PhdrI->p_vaddr, PhdrI->p_vaddr + PhdrI->p_filesz, - PhdrI->p_offset); + LoadMap->insert(Phdr.p_vaddr, Phdr.p_vaddr + Phdr.p_filesz, Phdr.p_offset); } auto toMappedAddr = [&](uint64_t VAddr) -> const uint8_t * { diff --git a/test/Object/Inputs/corrupt-invalid-phentsize.elf.x86-64 b/test/Object/Inputs/corrupt-invalid-phentsize.elf.x86-64 new file mode 100755 index 00000000000..148d4c5fd64 Binary files /dev/null and b/test/Object/Inputs/corrupt-invalid-phentsize.elf.x86-64 differ diff --git a/test/Object/corrupt.test b/test/Object/corrupt.test index 2181c7e8907..7c4b1c775ec 100644 --- a/test/Object/corrupt.test +++ b/test/Object/corrupt.test @@ -31,3 +31,9 @@ RUN: not llvm-readobj -dynamic-table %p/Inputs/corrupt-invalid-strtab.elf.x86-64 RUN: 2>&1 | FileCheck --check-prefix=STRTAB %s STRTAB: Invalid dynamic string table reference + +RUN: not llvm-readobj -program-headers \ +RUN: %p/Inputs/corrupt-invalid-phentsize.elf.x86-64 2>&1 | \ +RUN: FileCheck --check-prefix=PHENTSIZE %s + +PHENTSIZE: Invalid program header size diff --git a/tools/llvm-objdump/ELFDump.cpp b/tools/llvm-objdump/ELFDump.cpp index 2d0d7d7db0f..7b44e3916c4 100644 --- a/tools/llvm-objdump/ELFDump.cpp +++ b/tools/llvm-objdump/ELFDump.cpp @@ -24,10 +24,8 @@ using namespace llvm::object; template void printProgramHeaders(const ELFFile *o) { typedef ELFFile ELFO; outs() << "Program Header:\n"; - for (typename ELFO::Elf_Phdr_Iter pi = o->program_header_begin(), - pe = o->program_header_end(); - pi != pe; ++pi) { - switch (pi->p_type) { + for (const typename ELFO::Elf_Phdr &Phdr : o->program_headers()) { + switch (Phdr.p_type) { case ELF::PT_LOAD: outs() << " LOAD "; break; @@ -55,22 +53,16 @@ template void printProgramHeaders(const ELFFile *o) { const char *Fmt = ELFT::Is64Bits ? "0x%016" PRIx64 " " : "0x%08" PRIx64 " "; - outs() << "off " - << format(Fmt, (uint64_t)pi->p_offset) - << "vaddr " - << format(Fmt, (uint64_t)pi->p_vaddr) - << "paddr " - << format(Fmt, (uint64_t)pi->p_paddr) - << format("align 2**%u\n", countTrailingZeros(pi->p_align)) - << " filesz " - << format(Fmt, (uint64_t)pi->p_filesz) - << "memsz " - << format(Fmt, (uint64_t)pi->p_memsz) - << "flags " - << ((pi->p_flags & ELF::PF_R) ? "r" : "-") - << ((pi->p_flags & ELF::PF_W) ? "w" : "-") - << ((pi->p_flags & ELF::PF_X) ? "x" : "-") - << "\n"; + outs() << "off " << format(Fmt, (uint64_t)Phdr.p_offset) << "vaddr " + << format(Fmt, (uint64_t)Phdr.p_vaddr) << "paddr " + << format(Fmt, (uint64_t)Phdr.p_paddr) + << format("align 2**%u\n", + countTrailingZeros(Phdr.p_align)) + << " filesz " << format(Fmt, (uint64_t)Phdr.p_filesz) + << "memsz " << format(Fmt, (uint64_t)Phdr.p_memsz) << "flags " + << ((Phdr.p_flags & ELF::PF_R) ? "r" : "-") + << ((Phdr.p_flags & ELF::PF_W) ? "w" : "-") + << ((Phdr.p_flags & ELF::PF_X) ? "x" : "-") << "\n"; } outs() << "\n"; } diff --git a/tools/llvm-readobj/ELFDumper.cpp b/tools/llvm-readobj/ELFDumper.cpp index 045f4dfc636..1cd638c5415 100644 --- a/tools/llvm-readobj/ELFDumper.cpp +++ b/tools/llvm-readobj/ELFDumper.cpp @@ -1109,20 +1109,18 @@ template void ELFDumper::printProgramHeaders() { ListScope L(W, "ProgramHeaders"); - for (typename ELFO::Elf_Phdr_Iter PI = Obj->program_header_begin(), - PE = Obj->program_header_end(); - PI != PE; ++PI) { + for (const typename ELFO::Elf_Phdr &Phdr : Obj->program_headers()) { DictScope P(W, "ProgramHeader"); - W.printHex ("Type", - getElfSegmentType(Obj->getHeader()->e_machine, PI->p_type), - PI->p_type); - W.printHex ("Offset", PI->p_offset); - W.printHex ("VirtualAddress", PI->p_vaddr); - W.printHex ("PhysicalAddress", PI->p_paddr); - W.printNumber("FileSize", PI->p_filesz); - W.printNumber("MemSize", PI->p_memsz); - W.printFlags ("Flags", PI->p_flags, makeArrayRef(ElfSegmentFlags)); - W.printNumber("Alignment", PI->p_align); + W.printHex("Type", + getElfSegmentType(Obj->getHeader()->e_machine, Phdr.p_type), + Phdr.p_type); + W.printHex("Offset", Phdr.p_offset); + W.printHex("VirtualAddress", Phdr.p_vaddr); + W.printHex("PhysicalAddress", Phdr.p_paddr); + W.printNumber("FileSize", Phdr.p_filesz); + W.printNumber("MemSize", Phdr.p_memsz); + W.printFlags("Flags", Phdr.p_flags, makeArrayRef(ElfSegmentFlags)); + W.printNumber("Alignment", Phdr.p_align); } }