OSDN Git Service

Simplify iterating over program headers and detect corrupt ones.
authorRafael Espindola <rafael.espindola@gmail.com>
Mon, 20 Jul 2015 13:35:33 +0000 (13:35 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Mon, 20 Jul 2015 13:35:33 +0000 (13:35 +0000)
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

include/llvm/Object/ELF.h
test/Object/Inputs/corrupt-invalid-phentsize.elf.x86-64 [new file with mode: 0755]
test/Object/corrupt.test
tools/llvm-objdump/ELFDump.cpp
tools/llvm-readobj/ELFDumper.cpp

index cc27185..160b12d 100644 (file)
@@ -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 * {
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 (executable)
index 0000000..148d4c5
Binary files /dev/null and b/test/Object/Inputs/corrupt-invalid-phentsize.elf.x86-64 differ
index 2181c7e..7c4b1c7 100644 (file)
@@ -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
index 2d0d7d7..7b44e39 100644 (file)
@@ -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 printProgramHeaders(const ELFFile<ELFT> *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<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";
 }
index 045f4df..1cd638c 100644 (file)
@@ -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);
   }
 }