[llvm] r261107 - Represent the dynamic table itself with a DynRegionInfo.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 17 08:48:00 PST 2016


Author: rafael
Date: Wed Feb 17 10:48:00 2016
New Revision: 261107

URL: http://llvm.org/viewvc/llvm-project?rev=261107&view=rev
Log:
Represent the dynamic table itself with a DynRegionInfo.

The dynamic table is also an array of a fixed structure, so it can be
represented with a DynReginoInfo.

No major functionality change. The extra error checking is covered by
existing tests with a broken dynamic program header.

Idea extracted from r260488. I did the extra cleanups.

Modified:
    llvm/trunk/include/llvm/Object/ELF.h
    llvm/trunk/include/llvm/Object/Error.h
    llvm/trunk/lib/Object/Error.cpp
    llvm/trunk/test/Object/corrupt.test
    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=261107&r1=261106&r2=261107&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/ELF.h (original)
+++ llvm/trunk/include/llvm/Object/ELF.h Wed Feb 17 10:48:00 2016
@@ -62,6 +62,8 @@ public:
     return reinterpret_cast<const uint8_t *>(Buf.data());
   }
 
+  size_t getBufSize() const { return Buf.size(); }
+
 private:
 
   StringRef Buf;
@@ -104,18 +106,6 @@ public:
       Header->getDataEncoding() == ELF::ELFDATA2LSB;
   }
 
-  ErrorOr<const Elf_Dyn *> dynamic_table_begin(const Elf_Phdr *Phdr) const;
-  ErrorOr<const Elf_Dyn *> dynamic_table_end(const Elf_Phdr *Phdr) const;
-  ErrorOr<Elf_Dyn_Range> dynamic_table(const Elf_Phdr *Phdr) const {
-    ErrorOr<const Elf_Dyn *> Begin = dynamic_table_begin(Phdr);
-    if (std::error_code EC = Begin.getError())
-      return EC;
-    ErrorOr<const Elf_Dyn *> End = dynamic_table_end(Phdr);
-    if (std::error_code EC = End.getError())
-      return EC;
-    return make_range(*Begin, *End);
-  }
-
   const Elf_Shdr *section_begin() const;
   const Elf_Shdr *section_end() const;
   Elf_Shdr_Range sections() const {
@@ -414,34 +404,6 @@ const typename ELFFile<ELFT>::Elf_Shdr *
 }
 
 template <class ELFT>
-ErrorOr<const typename ELFFile<ELFT>::Elf_Dyn *>
-ELFFile<ELFT>::dynamic_table_begin(const Elf_Phdr *Phdr) const {
-  if (!Phdr)
-    return nullptr;
-  assert(Phdr->p_type == ELF::PT_DYNAMIC && "Got the wrong program header");
-  uintX_t Offset = Phdr->p_offset;
-  if (Offset > Buf.size())
-    return object_error::parse_failed;
-  return reinterpret_cast<const Elf_Dyn *>(base() + Offset);
-}
-
-template <class ELFT>
-ErrorOr<const typename ELFFile<ELFT>::Elf_Dyn *>
-ELFFile<ELFT>::dynamic_table_end(const Elf_Phdr *Phdr) const {
-  if (!Phdr)
-    return nullptr;
-  assert(Phdr->p_type == ELF::PT_DYNAMIC && "Got the wrong program header");
-  uintX_t Size = Phdr->p_filesz;
-  if (Size % sizeof(Elf_Dyn))
-    return object_error::elf_invalid_dynamic_table_size;
-  // FIKME: Check for overflow?
-  uintX_t End = Phdr->p_offset + Size;
-  if (End > Buf.size())
-    return object_error::parse_failed;
-  return reinterpret_cast<const Elf_Dyn *>(base() + End);
-}
-
-template <class ELFT>
 template <typename T>
 const T *ELFFile<ELFT>::getEntry(uint32_t Section, uint32_t Entry) const {
   ErrorOr<const Elf_Shdr *> Sec = getSection(Section);

Modified: llvm/trunk/include/llvm/Object/Error.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/Error.h?rev=261107&r1=261106&r2=261107&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/Error.h (original)
+++ llvm/trunk/include/llvm/Object/Error.h Wed Feb 17 10:48:00 2016
@@ -30,7 +30,6 @@ enum class object_error {
   string_table_non_null_end,
   invalid_section_index,
   bitcode_section_not_found,
-  elf_invalid_dynamic_table_size,
   macho_small_load_command,
   macho_load_segment_too_many_sections,
   macho_load_segment_too_small,

Modified: llvm/trunk/lib/Object/Error.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/Error.cpp?rev=261107&r1=261106&r2=261107&view=diff
==============================================================================
--- llvm/trunk/lib/Object/Error.cpp (original)
+++ llvm/trunk/lib/Object/Error.cpp Wed Feb 17 10:48:00 2016
@@ -47,8 +47,6 @@ std::string _object_error_category::mess
     return "Invalid section index";
   case object_error::bitcode_section_not_found:
     return "Bitcode section not found in object file";
-  case object_error::elf_invalid_dynamic_table_size:
-    return "Invalid dynamic table size";
   case object_error::macho_small_load_command:
     return "Mach-O load command with size < 8 bytes";
   case object_error::macho_load_segment_too_many_sections:

Modified: llvm/trunk/test/Object/corrupt.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/corrupt.test?rev=261107&r1=261106&r2=261107&view=diff
==============================================================================
--- llvm/trunk/test/Object/corrupt.test (original)
+++ llvm/trunk/test/Object/corrupt.test Wed Feb 17 10:48:00 2016
@@ -55,7 +55,7 @@ RUN: not llvm-readobj -dyn-relocations \
 RUN:   %p/Inputs/corrupt-invalid-dynamic-table-size.elf.x86-64 2>&1 | \
 RUN:   FileCheck --check-prefix=DYN-TABLE-SIZE %s
 
-DYN-TABLE-SIZE:  Invalid dynamic table size
+DYN-TABLE-SIZE:  Invalid entity size
 
 
 RUN: not llvm-readobj -dyn-relocations \

Modified: llvm/trunk/tools/llvm-readobj/ELFDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/ELFDumper.cpp?rev=261107&r1=261106&r2=261107&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/ELFDumper.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/ELFDumper.cpp Wed Feb 17 10:48:00 2016
@@ -127,8 +127,19 @@ private:
   typedef typename ELFO::Elf_Verdef Elf_Verdef;
   typedef typename ELFO::Elf_Verdaux Elf_Verdaux;
 
+  DynRegionInfo checkDRI(DynRegionInfo DRI) {
+    if (DRI.Addr < Obj->base() ||
+        (const uint8_t *)DRI.Addr + DRI.Size > Obj->base() + Obj->getBufSize())
+      error(llvm::object::object_error::parse_failed);
+    return DRI;
+  }
+
+  DynRegionInfo createDRIFrom(const Elf_Phdr *P, uintX_t EntSize) {
+    return checkDRI({Obj->base() + P->p_offset, P->p_filesz, EntSize});
+  }
+
   DynRegionInfo createDRIFrom(const Elf_Shdr *S) {
-    return {Obj->base() + S->sh_offset, S->sh_size, S->sh_entsize};
+    return checkDRI({Obj->base() + S->sh_offset, S->sh_size, S->sh_entsize});
   }
 
   void parseDynamicTable(ArrayRef<const Elf_Phdr *> LoadSegments);
@@ -145,12 +156,6 @@ private:
   Elf_Rel_Range dyn_rels() const;
   Elf_Rela_Range dyn_relas() const;
   StringRef getDynamicString(uint64_t Offset) const;
-  const Elf_Dyn *dynamic_table_begin() const {
-    return unwrapOrError(Obj->dynamic_table_begin(DynamicProgHeader));
-  }
-  const Elf_Dyn *dynamic_table_end() const {
-    return unwrapOrError(Obj->dynamic_table_end(DynamicProgHeader));
-  }
   StringRef getSymbolVersion(StringRef StrTab, const Elf_Sym *symb,
                              bool &IsDefault);
   void LoadVersionMap();
@@ -162,7 +167,7 @@ private:
   DynRegionInfo DynRelaRegion;
   DynRegionInfo DynPLTRelRegion;
   DynRegionInfo DynSymRegion;
-  const Elf_Phdr *DynamicProgHeader = nullptr;
+  DynRegionInfo DynamicTable;
   StringRef DynamicStringTable;
   StringRef SOName;
   const Elf_Hash *HashTable = nullptr;
@@ -199,7 +204,7 @@ private:
 
 public:
   Elf_Dyn_Range dynamic_table() const {
-    return unwrapOrError(Obj->dynamic_table(DynamicProgHeader));
+    return DynamicTable.getAsRange<Elf_Dyn>();
   }
 
   Elf_Sym_Range dynamic_symbols() const {
@@ -991,7 +996,7 @@ ELFDumper<ELFT>::ELFDumper(const ELFFile
   SmallVector<const Elf_Phdr *, 4> LoadSegments;
   for (const Elf_Phdr &Phdr : Obj->program_headers()) {
     if (Phdr.p_type == ELF::PT_DYNAMIC) {
-      DynamicProgHeader = &Phdr;
+      DynamicTable = createDRIFrom(&Phdr, sizeof(Elf_Dyn));
       continue;
     }
     if (Phdr.p_type != ELF::PT_LOAD || Phdr.p_filesz == 0)
@@ -1654,8 +1659,8 @@ template <> void ELFDumper<ELFType<suppo
 
 template<class ELFT>
 void ELFDumper<ELFT>::printDynamicTable() {
-  auto I = dynamic_table_begin();
-  auto E = dynamic_table_end();
+  auto I = dynamic_table().begin();
+  auto E = dynamic_table().end();
 
   if (I == E)
     return;




More information about the llvm-commits mailing list