[llvm] r260245 - [llvm-readobj][ELF] Show MIPS GOT content when there is another zero-sized section at the same address

Simon Atanasyan via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 9 10:45:36 PST 2016


Author: atanasyan
Date: Tue Feb  9 12:45:35 2016
New Revision: 260245

URL: http://llvm.org/viewvc/llvm-project?rev=260245&view=rev
Log:
[llvm-readobj][ELF] Show MIPS GOT content when there is another zero-sized section at the same address

It is possible to have .got section and one or more zero-sized section
at the same address. This patch first checks that GOT (or GOT PLT)
section should have non-zero size using corresponding dynamic tags. Then
it looks up not empty section at the specified address.

Differential Revision: http://reviews.llvm.org/D16968

Added:
    llvm/trunk/test/tools/llvm-readobj/Inputs/got-over.exe.elf-mips   (with props)
    llvm/trunk/test/tools/llvm-readobj/mips-got-overlapped.test
Modified:
    llvm/trunk/tools/llvm-readobj/ELFDumper.cpp

Added: llvm/trunk/test/tools/llvm-readobj/Inputs/got-over.exe.elf-mips
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/Inputs/got-over.exe.elf-mips?rev=260245&view=auto
==============================================================================
Binary files llvm/trunk/test/tools/llvm-readobj/Inputs/got-over.exe.elf-mips (added) and llvm/trunk/test/tools/llvm-readobj/Inputs/got-over.exe.elf-mips Tue Feb  9 12:45:35 2016 differ

Propchange: llvm/trunk/test/tools/llvm-readobj/Inputs/got-over.exe.elf-mips
------------------------------------------------------------------------------
    svn:executable = *

Added: llvm/trunk/test/tools/llvm-readobj/mips-got-overlapped.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/mips-got-overlapped.test?rev=260245&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-readobj/mips-got-overlapped.test (added)
+++ llvm/trunk/test/tools/llvm-readobj/mips-got-overlapped.test Tue Feb  9 12:45:35 2016
@@ -0,0 +1,45 @@
+# Check that llvm-readobj -mips-plt-got correctly shows .got section
+# content if there are some other zero-sized sections with the same
+# address as the .got. got-over.exe.elf-mips has zero-sized .data
+# section at the same offset .got section.
+
+RUN: llvm-readobj -mips-plt-got %p/Inputs/got-over.exe.elf-mips | FileCheck %s
+
+GOT-OBJ: Cannot find PLTGOT dynamic table tag.
+
+CHECK:      Primary GOT {
+CHECK-NEXT:   Canonical gp value: 0x418270
+CHECK-NEXT:   Reserved entries [
+CHECK-NEXT:     Entry {
+CHECK-NEXT:       Address: 0x410280
+CHECK-NEXT:       Access: -32752
+CHECK-NEXT:       Initial: 0x0
+CHECK-NEXT:       Purpose: Lazy resolver
+CHECK-NEXT:     }
+CHECK-NEXT:     Entry {
+CHECK-NEXT:       Address: 0x410284
+CHECK-NEXT:       Access: -32748
+CHECK-NEXT:       Initial: 0x80000000
+CHECK-NEXT:       Purpose: Module pointer (GNU extension)
+CHECK-NEXT:     }
+CHECK-NEXT:   ]
+CHECK-NEXT:   Local entries [
+CHECK-NEXT:     Entry {
+CHECK-NEXT:       Address: 0x410288
+CHECK-NEXT:       Access: -32744
+CHECK-NEXT:       Initial: 0x4001B8
+CHECK-NEXT:     }
+CHECK-NEXT:   ]
+CHECK-NEXT:   Global entries [
+CHECK-NEXT:     Entry {
+CHECK-NEXT:       Address: 0x41028C
+CHECK-NEXT:       Access: -32740
+CHECK-NEXT:       Initial: 0x0
+CHECK-NEXT:       Value: 0x0
+CHECK-NEXT:       Type: None
+CHECK-NEXT:       Section: Undefined
+CHECK-NEXT:       Name: _foo
+CHECK-NEXT:     }
+CHECK-NEXT:   ]
+CHECK-NEXT:   Number of TLS and multi-GOT entries: 0
+CHECK-NEXT: }

Modified: llvm/trunk/tools/llvm-readobj/ELFDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/ELFDumper.cpp?rev=260245&r1=260244&r2=260245&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/ELFDumper.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/ELFDumper.cpp Tue Feb  9 12:45:35 2016
@@ -497,10 +497,10 @@ getSectionNameIndex(const ELFO &Obj, con
 }
 
 template <class ELFO>
-static const typename ELFO::Elf_Shdr *findSectionByAddress(const ELFO *Obj,
-                                                           uint64_t Addr) {
+static const typename ELFO::Elf_Shdr *
+findNotEmptySectionByAddress(const ELFO *Obj, uint64_t Addr) {
   for (const auto &Shdr : Obj->sections())
-    if (Shdr.sh_addr == Addr)
+    if (Shdr.sh_addr == Addr && Shdr.sh_size > 0)
       return &Shdr;
   return nullptr;
 }
@@ -1865,23 +1865,6 @@ template <class ELFT> void MipsGOTParser
     return;
   }
 
-  const Elf_Shdr *GOTShdr = findSectionByAddress(Obj, *DtPltGot);
-  if (!GOTShdr) {
-    W.startLine() << "There is no .got section in the file.\n";
-    return;
-  }
-
-  ErrorOr<ArrayRef<uint8_t>> GOT = Obj->getSectionContents(GOTShdr);
-  if (!GOT) {
-    W.startLine() << "The .got section is empty.\n";
-    return;
-  }
-
-  if (*DtLocalGotNum > getGOTTotal(*GOT)) {
-    W.startLine() << "MIPS_LOCAL_GOTNO exceeds a number of GOT entries.\n";
-    return;
-  }
-
   const Elf_Shdr *DynSymSec = Dumper->getDotDynSymSec();
   ErrorOr<StringRef> StrTable = Obj->getStringTableForSymtab(*DynSymSec);
   error(StrTable.getError());
@@ -1889,18 +1872,26 @@ template <class ELFT> void MipsGOTParser
   const Elf_Sym *DynSymEnd = Obj->symbol_end(DynSymSec);
   std::size_t DynSymTotal = std::size_t(std::distance(DynSymBegin, DynSymEnd));
 
-  if (*DtGotSym > DynSymTotal) {
-    W.startLine() << "MIPS_GOTSYM exceeds a number of dynamic symbols.\n";
-    return;
-  }
+  if (*DtGotSym > DynSymTotal)
+    report_fatal_error("MIPS_GOTSYM exceeds a number of dynamic symbols");
 
   std::size_t GlobalGotNum = DynSymTotal - *DtGotSym;
 
-  if (*DtLocalGotNum + GlobalGotNum > getGOTTotal(*GOT)) {
-    W.startLine() << "Number of global GOT entries exceeds the size of GOT.\n";
+  if (*DtLocalGotNum + GlobalGotNum == 0) {
+    W.startLine() << "GOT is empty.\n";
     return;
   }
 
+  const Elf_Shdr *GOTShdr = findNotEmptySectionByAddress(Obj, *DtPltGot);
+  if (!GOTShdr)
+    report_fatal_error("There is no not empty GOT section at 0x" +
+                       Twine::utohexstr(*DtPltGot));
+
+  ErrorOr<ArrayRef<uint8_t>> GOT = Obj->getSectionContents(GOTShdr);
+
+  if (*DtLocalGotNum + GlobalGotNum > getGOTTotal(*GOT))
+    report_fatal_error("Number of GOT entries exceeds the size of GOT section");
+
   const GOTEntry *GotBegin = makeGOTIter(*GOT, 0);
   const GOTEntry *GotLocalEnd = makeGOTIter(*GOT, *DtLocalGotNum);
   const GOTEntry *It = GotBegin;
@@ -1957,22 +1948,16 @@ template <class ELFT> void MipsGOTParser
     return;
   }
 
-  const Elf_Shdr *PLTShdr = findSectionByAddress(Obj, *DtMipsPltGot);
-  if (!PLTShdr) {
-    W.startLine() << "There is no .got.plt section in the file.\n";
-    return;
-  }
+  const Elf_Shdr *PLTShdr = findNotEmptySectionByAddress(Obj, *DtMipsPltGot);
+  if (!PLTShdr)
+    report_fatal_error("There is no not empty PLTGOT section at 0x " +
+                       Twine::utohexstr(*DtMipsPltGot));
   ErrorOr<ArrayRef<uint8_t>> PLT = Obj->getSectionContents(PLTShdr);
-  if (!PLT) {
-    W.startLine() << "The .got.plt section is empty.\n";
-    return;
-  }
 
-  const Elf_Shdr *PLTRelShdr = findSectionByAddress(Obj, *DtJmpRel);
-  if (!PLTShdr) {
-    W.startLine() << "There is no .rel.plt section in the file.\n";
-    return;
-  }
+  const Elf_Shdr *PLTRelShdr = findNotEmptySectionByAddress(Obj, *DtJmpRel);
+  if (!PLTRelShdr)
+    report_fatal_error("There is no not empty RELPLT section at 0x" +
+                       Twine::utohexstr(*DtJmpRel));
   ErrorOr<const Elf_Shdr *> SymTableOrErr =
       Obj->getSection(PLTRelShdr->sh_link);
   error(SymTableOrErr.getError());




More information about the llvm-commits mailing list