[llvm] r319616 - [llvm-readobj] Print static MIPS GOT

Simon Atanasyan via llvm-commits llvm-commits at lists.llvm.org
Sat Dec 2 05:06:35 PST 2017


Author: atanasyan
Date: Sat Dec  2 05:06:35 2017
New Revision: 319616

URL: http://llvm.org/viewvc/llvm-project?rev=319616&view=rev
Log:
[llvm-readobj] Print static MIPS GOT

If a linked binary file contains a dynamic section, the GOT layout
defined by the dynamic section entries. In a statically linked file
the GOT is just a series of entries. This change teaches `llvm-readobj`
to print the GOT in that case. That provides a feature parity with GNU
`readelf`.

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

Added: llvm/trunk/test/tools/llvm-readobj/Inputs/got-static.exe.mips
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/Inputs/got-static.exe.mips?rev=319616&view=auto
==============================================================================
Binary files llvm/trunk/test/tools/llvm-readobj/Inputs/got-static.exe.mips (added) and llvm/trunk/test/tools/llvm-readobj/Inputs/got-static.exe.mips Sat Dec  2 05:06:35 2017 differ

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

Modified: llvm/trunk/test/tools/llvm-readobj/mips-got.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/mips-got.test?rev=319616&r1=319615&r2=319616&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-readobj/mips-got.test (original)
+++ llvm/trunk/test/tools/llvm-readobj/mips-got.test Sat Dec  2 05:06:35 2017
@@ -8,8 +8,10 @@ RUN: llvm-readobj -mips-plt-got %p/Input
 RUN:   FileCheck %s -check-prefix GOT-TLS
 RUN: llvm-readobj -mips-plt-got %p/Inputs/got-empty.exe.mipsel | \
 RUN:   FileCheck %s -check-prefix GOT-EMPTY
+RUN: llvm-readobj -mips-plt-got %p/Inputs/got-static.exe.mips | \
+RUN:   FileCheck %s -check-prefix GOT-STATIC
 
-GOT-OBJ: Cannot find PLTGOT dynamic table tag.
+GOT-OBJ: Cannot find .got section
 
 GOT-EXE:      Primary GOT {
 GOT-EXE-NEXT:   Canonical gp value: 0x418880
@@ -329,3 +331,38 @@ GOT-EMPTY-NEXT:   Global entries [
 GOT-EMPTY-NEXT:   ]
 GOT-EMPTY-NEXT:   Number of TLS and multi-GOT entries: 2
 GOT-EMPTY-NEXT: }
+
+GOT-STATIC:      Static GOT {
+GOT-STATIC-NEXT:   Canonical gp value: 0x418100
+GOT-STATIC-NEXT:   Reserved entries [
+GOT-STATIC-NEXT:     Entry {
+GOT-STATIC-NEXT:       Address: 0x410110
+GOT-STATIC-NEXT:       Access: -32752
+GOT-STATIC-NEXT:       Initial: 0x0
+GOT-STATIC-NEXT:       Purpose: Lazy resolver
+GOT-STATIC-NEXT:     }
+GOT-STATIC-NEXT:     Entry {
+GOT-STATIC-NEXT:       Address: 0x410114
+GOT-STATIC-NEXT:       Access: -32748
+GOT-STATIC-NEXT:       Initial: 0x80000000
+GOT-STATIC-NEXT:       Purpose: Module pointer (GNU extension)
+GOT-STATIC-NEXT:     }
+GOT-STATIC-NEXT:   ]
+GOT-STATIC-NEXT:   Local entries [
+GOT-STATIC-NEXT:     Entry {
+GOT-STATIC-NEXT:       Address: 0x410118
+GOT-STATIC-NEXT:       Access: -32744
+GOT-STATIC-NEXT:       Initial: 0x400000
+GOT-STATIC-NEXT:     }
+GOT-STATIC-NEXT:     Entry {
+GOT-STATIC-NEXT:       Address: 0x41011C
+GOT-STATIC-NEXT:       Access: -32740
+GOT-STATIC-NEXT:       Initial: 0x400100
+GOT-STATIC-NEXT:     }
+GOT-STATIC-NEXT:     Entry {
+GOT-STATIC-NEXT:       Address: 0x410120
+GOT-STATIC-NEXT:       Access: -32736
+GOT-STATIC-NEXT:       Initial: 0x400104
+GOT-STATIC-NEXT:     }
+GOT-STATIC-NEXT:   ]
+GOT-STATIC-NEXT: }

Modified: llvm/trunk/tools/llvm-readobj/ELFDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/ELFDumper.cpp?rev=319616&r1=319615&r2=319616&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/ELFDumper.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/ELFDumper.cpp Sat Dec  2 05:06:35 2017
@@ -1910,6 +1910,7 @@ public:
   MipsGOTParser(ELFDumper<ELFT> *Dumper, const ELFO *Obj,
                 Elf_Dyn_Range DynTable, ScopedPrinter &W);
 
+  void parseStaticGOT();
   void parseGOT();
   void parsePLT();
 
@@ -1926,6 +1927,7 @@ private:
   std::size_t getGOTTotal(ArrayRef<uint8_t> GOT) const;
   const GOTEntry *makeGOTIter(ArrayRef<uint8_t> GOT, std::size_t EntryNum);
 
+  void printLocalGOT(const Elf_Shdr *GOTShdr, size_t Num);
   void printGotEntry(uint64_t GotAddr, const GOTEntry *BeginIt,
                      const GOTEntry *It);
   void printGlobalGotEntry(uint64_t GotAddr, const GOTEntry *BeginIt,
@@ -1965,6 +1967,50 @@ MipsGOTParser<ELFT>::MipsGOTParser(ELFDu
   }
 }
 
+template <class ELFT>
+void MipsGOTParser<ELFT>::printLocalGOT(const Elf_Shdr *GOTShdr, size_t Num) {
+  ArrayRef<uint8_t> GOT = unwrapOrError(Obj->getSectionContents(GOTShdr));
+
+  const GOTEntry *GotBegin = makeGOTIter(GOT, 0);
+  const GOTEntry *GotEnd = makeGOTIter(GOT, Num);
+  const GOTEntry *It = GotBegin;
+
+  W.printHex("Canonical gp value", GOTShdr->sh_addr + 0x7ff0);
+  {
+    ListScope RS(W, "Reserved entries");
+
+    {
+      DictScope D(W, "Entry");
+      printGotEntry(GOTShdr->sh_addr, GotBegin, It++);
+      W.printString("Purpose", StringRef("Lazy resolver"));
+    }
+
+    if (It != GotEnd && (*It >> (sizeof(GOTEntry) * 8 - 1)) != 0) {
+      DictScope D(W, "Entry");
+      printGotEntry(GOTShdr->sh_addr, GotBegin, It++);
+      W.printString("Purpose", StringRef("Module pointer (GNU extension)"));
+    }
+  }
+  {
+    ListScope LS(W, "Local entries");
+    for (; It != GotEnd; ++It) {
+      DictScope D(W, "Entry");
+      printGotEntry(GOTShdr->sh_addr, GotBegin, It);
+    }
+  }
+}
+
+template <class ELFT> void MipsGOTParser<ELFT>::parseStaticGOT() {
+  const Elf_Shdr *GOTShdr = findSectionByName(*Obj, ".got");
+  if (!GOTShdr) {
+    W.startLine() << "Cannot find .got section.\n";
+    return;
+  }
+
+  DictScope GS(W, "Static GOT");
+  printLocalGOT(GOTShdr, GOTShdr->sh_size / sizeof(GOTEntry));
+}
+
 template <class ELFT> void MipsGOTParser<ELFT>::parseGOT() {
   // See "Global Offset Table" in Chapter 5 in the following document
   // for detailed GOT description.
@@ -2007,42 +2053,17 @@ template <class ELFT> void MipsGOTParser
   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;
-
   DictScope GS(W, "Primary GOT");
+  printLocalGOT(GOTShdr, *DtLocalGotNum);
 
-  W.printHex("Canonical gp value", GOTShdr->sh_addr + 0x7ff0);
-  {
-    ListScope RS(W, "Reserved entries");
-
-    {
-      DictScope D(W, "Entry");
-      printGotEntry(GOTShdr->sh_addr, GotBegin, It++);
-      W.printString("Purpose", StringRef("Lazy resolver"));
-    }
-
-    if (It != GotLocalEnd && (*It >> (sizeof(GOTEntry) * 8 - 1)) != 0) {
-      DictScope D(W, "Entry");
-      printGotEntry(GOTShdr->sh_addr, GotBegin, It++);
-      W.printString("Purpose", StringRef("Module pointer (GNU extension)"));
-    }
-  }
-  {
-    ListScope LS(W, "Local entries");
-    for (; It != GotLocalEnd; ++It) {
-      DictScope D(W, "Entry");
-      printGotEntry(GOTShdr->sh_addr, GotBegin, It);
-    }
-  }
   {
     ListScope GS(W, "Global entries");
 
+    const GOTEntry *GotBegin = makeGOTIter(GOT, 0);
     const GOTEntry *GotGlobalEnd =
         makeGOTIter(GOT, *DtLocalGotNum + GlobalGotNum);
     const Elf_Sym *GotDynSym = DynSymBegin + *DtGotSym;
-    for (; It != GotGlobalEnd; ++It) {
+    for (auto It = makeGOTIter(GOT, *DtLocalGotNum); It != GotGlobalEnd; ++It) {
       DictScope D(W, "Entry");
       printGlobalGotEntry(GOTShdr->sh_addr, GotBegin, It, GotDynSym++,
                           StrTable);
@@ -2197,8 +2218,12 @@ template <class ELFT> void ELFDumper<ELF
   }
 
   MipsGOTParser<ELFT> GOTParser(this, Obj, dynamic_table(), W);
-  GOTParser.parseGOT();
-  GOTParser.parsePLT();
+  if (dynamic_table().empty())
+    GOTParser.parseStaticGOT();
+  else {
+    GOTParser.parseGOT();
+    GOTParser.parsePLT();
+  }
 }
 
 static const EnumEntry<unsigned> ElfMipsISAExtType[] = {




More information about the llvm-commits mailing list