[llvm] r242669 - Simplify iterating over program headers and detect corrupt ones.

Rafael Espindola rafael.espindola at gmail.com
Mon Jul 20 06:35:47 PDT 2015


Author: rafael
Date: Mon Jul 20 08:35:33 2015
New Revision: 242669

URL: http://llvm.org/viewvc/llvm-project?rev=242669&view=rev
Log:
Simplify iterating over program headers and detect corrupt ones.

We now use a simple pointer and have range loops.

Added:
    llvm/trunk/test/Object/Inputs/corrupt-invalid-phentsize.elf.x86-64   (with props)
Modified:
    llvm/trunk/include/llvm/Object/ELF.h
    llvm/trunk/test/Object/corrupt.test
    llvm/trunk/tools/llvm-objdump/ELFDump.cpp
    llvm/trunk/tools/llvm-readobj/ELFDumper.cpp

Modified: llvm/trunk/include/llvm/Object/ELF.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/ELF.h?rev=242669&r1=242668&r2=242669&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/ELF.h (original)
+++ llvm/trunk/include/llvm/Object/ELF.h Mon Jul 20 08:35:33 2015
@@ -349,18 +349,20 @@ public:
   }
 
   /// \brief Iterate over program header table.
-  typedef ELFEntityIterator<const Elf_Phdr> 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<const Elf_Phdr *>(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<const Elf_Phdr *> 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<ELFT>::scanDynamicTable() {
   // stack doesn't get realigned despite LoadMap having alignment 8 (PR24113).
   std::unique_ptr<LoadMapT> 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 * {

Added: llvm/trunk/test/Object/Inputs/corrupt-invalid-phentsize.elf.x86-64
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/Inputs/corrupt-invalid-phentsize.elf.x86-64?rev=242669&view=auto
==============================================================================
Binary files llvm/trunk/test/Object/Inputs/corrupt-invalid-phentsize.elf.x86-64 (added) and llvm/trunk/test/Object/Inputs/corrupt-invalid-phentsize.elf.x86-64 Mon Jul 20 08:35:33 2015 differ

Propchange: llvm/trunk/test/Object/Inputs/corrupt-invalid-phentsize.elf.x86-64
------------------------------------------------------------------------------
    svn:executable = *

Modified: llvm/trunk/test/Object/corrupt.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/corrupt.test?rev=242669&r1=242668&r2=242669&view=diff
==============================================================================
--- llvm/trunk/test/Object/corrupt.test (original)
+++ llvm/trunk/test/Object/corrupt.test Mon Jul 20 08:35:33 2015
@@ -31,3 +31,9 @@ RUN: not llvm-readobj -dynamic-table %p/
 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

Modified: llvm/trunk/tools/llvm-objdump/ELFDump.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/ELFDump.cpp?rev=242669&r1=242668&r2=242669&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objdump/ELFDump.cpp (original)
+++ llvm/trunk/tools/llvm-objdump/ELFDump.cpp Mon Jul 20 08:35:33 2015
@@ -24,10 +24,8 @@ using namespace llvm::object;
 template <class ELFT> void printProgramHeaders(const ELFFile<ELFT> *o) {
   typedef ELFFile<ELFT> 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 <class ELFT> void printProgramH
 
     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<uint64_t>(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<uint64_t>(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";
 }

Modified: llvm/trunk/tools/llvm-readobj/ELFDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/ELFDumper.cpp?rev=242669&r1=242668&r2=242669&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/ELFDumper.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/ELFDumper.cpp Mon Jul 20 08:35:33 2015
@@ -1109,20 +1109,18 @@ template<class ELFT>
 void ELFDumper<ELFT>::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);
   }
 }
 





More information about the llvm-commits mailing list