Remove Elf_Rela_Iter and Elf_Rel_Iter.
authorRafael Espindola <rafael.espindola@gmail.com>
Mon, 20 Jul 2015 20:07:50 +0000 (20:07 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Mon, 20 Jul 2015 20:07:50 +0000 (20:07 +0000)
Use just the pointers and check for invalid relocation sections.

llvm-svn: 242700

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

index 509355b..e5a419c 100644 (file)
@@ -142,8 +142,6 @@ public:
   typedef Elf_Hash_Impl<ELFT> Elf_Hash;
   typedef ELFEntityIterator<const Elf_Dyn> Elf_Dyn_Iter;
   typedef iterator_range<Elf_Dyn_Iter> Elf_Dyn_Range;
-  typedef ELFEntityIterator<const Elf_Rela> Elf_Rela_Iter;
-  typedef ELFEntityIterator<const Elf_Rel> Elf_Rel_Iter;
   typedef iterator_range<const Elf_Shdr *> Elf_Shdr_Range;
 
   /// \brief Archive files are 2 byte aligned, so we need this for
@@ -311,40 +309,58 @@ public:
     return make_range(dynamic_symbol_begin(), dynamic_symbol_end());
   }
 
-  Elf_Rela_Iter dyn_rela_begin() const {
-    if (DynRelaRegion.Addr)
-      return Elf_Rela_Iter(DynRelaRegion.EntSize,
-        (const char *)DynRelaRegion.Addr);
-    return Elf_Rela_Iter(0, nullptr);
+  const Elf_Rela *dyn_rela_begin() const {
+    if (DynRelaRegion.Size && DynRelaRegion.EntSize != sizeof(Elf_Rela))
+      report_fatal_error("Invalid relocation entry size");
+    return reinterpret_cast<const Elf_Rela *>(DynRelaRegion.Addr);
   }
 
-  Elf_Rela_Iter dyn_rela_end() const {
-    if (DynRelaRegion.Addr)
-      return Elf_Rela_Iter(
-        DynRelaRegion.EntSize,
-        (const char *)DynRelaRegion.Addr + DynRelaRegion.Size);
-    return Elf_Rela_Iter(0, nullptr);
+  const Elf_Rela *dyn_rela_end() const {
+    uint64_t Size = DynRelaRegion.Size;
+    if (Size % sizeof(Elf_Rela))
+      report_fatal_error("Invalid relocation table size");
+    return dyn_rela_begin() + Size / sizeof(Elf_Rela);
   }
 
-  Elf_Rela_Iter rela_begin(const Elf_Shdr *sec) const {
-    return Elf_Rela_Iter(sec->sh_entsize,
-                         (const char *)(base() + sec->sh_offset));
+  typedef iterator_range<const Elf_Rela *> Elf_Rela_Range;
+
+  Elf_Rela_Range dyn_relas() const {
+    return make_range(dyn_rela_begin(), dyn_rela_end());
+  }
+
+  const Elf_Rela *rela_begin(const Elf_Shdr *sec) const {
+    if (sec->sh_entsize != sizeof(Elf_Rela))
+      report_fatal_error("Invalid relocation entry size");
+    return reinterpret_cast<const Elf_Rela *>(base() + sec->sh_offset);
+  }
+
+  const Elf_Rela *rela_end(const Elf_Shdr *sec) const {
+    uint64_t Size = sec->sh_size;
+    if (Size % sizeof(Elf_Rela))
+      report_fatal_error("Invalid relocation table size");
+    return rela_begin(sec) + Size / sizeof(Elf_Rela);
+  }
+
+  Elf_Rela_Range relas(const Elf_Shdr *Sec) const {
+    return make_range(rela_begin(Sec), rela_end(Sec));
   }
 
-  Elf_Rela_Iter rela_end(const Elf_Shdr *sec) const {
-    return Elf_Rela_Iter(
-        sec->sh_entsize,
-        (const char *)(base() + sec->sh_offset + sec->sh_size));
+  const Elf_Rel *rel_begin(const Elf_Shdr *sec) const {
+    if (sec->sh_entsize != sizeof(Elf_Rel))
+      report_fatal_error("Invalid relocation entry size");
+    return reinterpret_cast<const Elf_Rel *>(base() + sec->sh_offset);
   }
 
-  Elf_Rel_Iter rel_begin(const Elf_Shdr *sec) const {
-    return Elf_Rel_Iter(sec->sh_entsize,
-                        (const char *)(base() + sec->sh_offset));
+  const Elf_Rel *rel_end(const Elf_Shdr *sec) const {
+    uint64_t Size = sec->sh_size;
+    if (Size % sizeof(Elf_Rel))
+      report_fatal_error("Invalid relocation table size");
+    return rel_begin(sec) + Size / sizeof(Elf_Rel);
   }
 
-  Elf_Rel_Iter rel_end(const Elf_Shdr *sec) const {
-    return Elf_Rel_Iter(sec->sh_entsize,
-                        (const char *)(base() + sec->sh_offset + sec->sh_size));
+  typedef iterator_range<const Elf_Rel *> Elf_Rel_Range;
+  Elf_Rel_Range rels(const Elf_Shdr *Sec) const {
+    return make_range(rel_begin(Sec), rel_end(Sec));
   }
 
   /// \brief Iterate over program header table.
diff --git a/llvm/test/Object/Inputs/corrupt-invalid-relocation-size.elf.x86-64 b/llvm/test/Object/Inputs/corrupt-invalid-relocation-size.elf.x86-64
new file mode 100755 (executable)
index 0000000..2798ab3
Binary files /dev/null and b/llvm/test/Object/Inputs/corrupt-invalid-relocation-size.elf.x86-64 differ
index 9b3daf7..843cc24 100644 (file)
@@ -43,3 +43,10 @@ RUN:   %p/Inputs/corrupt-invalid-virtual-addr.elf.x86-64 2>&1 | \
 RUN:   FileCheck --check-prefix=VIRTADDR %s
 
 VIRTADDR: Virtual address is not in any segment
+
+
+RUN: not llvm-readobj -dyn-relocations \
+RUN:   %p/Inputs/corrupt-invalid-relocation-size.elf.x86-64 2>&1 | \
+RUN:   FileCheck --check-prefix=RELOC %s
+
+RELOC:  Invalid relocation entry size
index dd2490d..b223770 100644 (file)
@@ -310,8 +310,7 @@ class PrinterContext {
 
   typedef typename object::ELFFile<ET>::Elf_Sym Elf_Sym;
   typedef typename object::ELFFile<ET>::Elf_Shdr Elf_Shdr;
-
-  typedef typename object::ELFFile<ET>::Elf_Rel_Iter Elf_Rel_iterator;
+  typedef typename object::ELFFile<ET>::Elf_Rel Elf_Rel;
 
   static const size_t IndexTableEntrySize;
 
@@ -366,12 +365,11 @@ PrinterContext<ET>::FindExceptionTable(unsigned IndexSectionIndex,
 
   for (const Elf_Shdr &Sec : ELF->sections()) {
     if (Sec.sh_type == ELF::SHT_REL && Sec.sh_info == IndexSectionIndex) {
-      for (Elf_Rel_iterator RI = ELF->rel_begin(&Sec), RE = ELF->rel_end(&Sec);
-           RI != RE; ++RI) {
-        if (RI->r_offset == static_cast<unsigned>(IndexTableOffset)) {
+      for (const Elf_Rel &R : ELF->rels(&Sec)) {
+        if (R.r_offset == static_cast<unsigned>(IndexTableOffset)) {
           typename object::ELFFile<ET>::Elf_Rela RelA;
-          RelA.r_offset = RI->r_offset;
-          RelA.r_info = RI->r_info;
+          RelA.r_offset = R.r_offset;
+          RelA.r_info = R.r_info;
           RelA.r_addend = 0;
 
           std::pair<const Elf_Shdr *, const Elf_Sym *> Symbol =
index 1cd638c..df85e76 100644 (file)
@@ -689,29 +689,25 @@ template<class ELFT>
 void ELFDumper<ELFT>::printDynamicRelocations() {
   W.startLine() << "Dynamic Relocations {\n";
   W.indent();
-  for (typename ELFO::Elf_Rela_Iter RelI = Obj->dyn_rela_begin(),
-                                    RelE = Obj->dyn_rela_end();
-       RelI != RelE; ++RelI) {
+  for (const typename ELFO::Elf_Rela &Rel : Obj->dyn_relas()) {
     SmallString<32> RelocName;
-    Obj->getRelocationTypeName(RelI->getType(Obj->isMips64EL()), RelocName);
+    Obj->getRelocationTypeName(Rel.getType(Obj->isMips64EL()), RelocName);
     StringRef SymbolName;
-    uint32_t SymIndex = RelI->getSymbol(Obj->isMips64EL());
+    uint32_t SymIndex = Rel.getSymbol(Obj->isMips64EL());
     const typename ELFO::Elf_Sym *Sym = Obj->dynamic_symbol_begin() + SymIndex;
     SymbolName = errorOrDefault(Obj->getSymbolName(Sym, true));
     if (opts::ExpandRelocs) {
       DictScope Group(W, "Relocation");
-      W.printHex("Offset", RelI->r_offset);
-      W.printNumber("Type", RelocName, (int)RelI->getType(Obj->isMips64EL()));
+      W.printHex("Offset", Rel.r_offset);
+      W.printNumber("Type", RelocName, (int)Rel.getType(Obj->isMips64EL()));
       W.printString("Symbol", SymbolName.size() > 0 ? SymbolName : "-");
-      W.printHex("Addend", RelI->r_addend);
+      W.printHex("Addend", Rel.r_addend);
     }
     else {
       raw_ostream& OS = W.startLine();
-      OS << W.hex(RelI->r_offset)
-        << " " << RelocName
-        << " " << (SymbolName.size() > 0 ? SymbolName : "-")
-        << " " << W.hex(RelI->r_addend)
-        << "\n";
+      OS << W.hex(Rel.r_offset) << " " << RelocName << " "
+         << (SymbolName.size() > 0 ? SymbolName : "-") << " "
+         << W.hex(Rel.r_addend) << "\n";
     }
   }
   W.unindent();
@@ -722,22 +718,17 @@ template <class ELFT>
 void ELFDumper<ELFT>::printRelocations(const Elf_Shdr *Sec) {
   switch (Sec->sh_type) {
   case ELF::SHT_REL:
-    for (typename ELFO::Elf_Rel_Iter RI = Obj->rel_begin(Sec),
-                                     RE = Obj->rel_end(Sec);
-         RI != RE; ++RI) {
+    for (const typename ELFO::Elf_Rel &R : Obj->rels(Sec)) {
       typename ELFO::Elf_Rela Rela;
-      Rela.r_offset = RI->r_offset;
-      Rela.r_info = RI->r_info;
+      Rela.r_offset = R.r_offset;
+      Rela.r_info = R.r_info;
       Rela.r_addend = 0;
       printRelocation(Sec, Rela);
     }
     break;
   case ELF::SHT_RELA:
-    for (typename ELFO::Elf_Rela_Iter RI = Obj->rela_begin(Sec),
-                                      RE = Obj->rela_end(Sec);
-         RI != RE; ++RI) {
-      printRelocation(Sec, *RI);
-    }
+    for (const typename ELFO::Elf_Rela &R : Obj->relas(Sec))
+      printRelocation(Sec, R);
     break;
   }
 }
@@ -1371,8 +1362,8 @@ template <class ELFT> void MipsGOTParser<ELFT>::parsePLT() {
 
     switch (PLTRelShdr->sh_type) {
     case ELF::SHT_REL:
-      for (typename ObjectFile::Elf_Rel_Iter RI = Obj->rel_begin(PLTRelShdr),
-                                             RE = Obj->rel_end(PLTRelShdr);
+      for (const typename ObjectFile::Elf_Rel *RI = Obj->rel_begin(PLTRelShdr),
+                                              *RE = Obj->rel_end(PLTRelShdr);
            RI != RE && It != PLTEnd; ++RI, ++It) {
         const Elf_Sym *Sym =
             Obj->getRelocationSymbol(&*PLTRelShdr, &*RI).second;
@@ -1380,8 +1371,9 @@ template <class ELFT> void MipsGOTParser<ELFT>::parsePLT() {
       }
       break;
     case ELF::SHT_RELA:
-      for (typename ObjectFile::Elf_Rela_Iter RI = Obj->rela_begin(PLTRelShdr),
-                                              RE = Obj->rela_end(PLTRelShdr);
+      for (const typename ObjectFile::Elf_Rela
+             *RI = Obj->rela_begin(PLTRelShdr),
+             *RE = Obj->rela_end(PLTRelShdr);
            RI != RE && It != PLTEnd; ++RI, ++It) {
         const Elf_Sym *Sym =
             Obj->getRelocationSymbol(&*PLTRelShdr, &*RI).second;