[llvm] r354782 - [llvm-objdump] Add `Version References` dumper

Xing GUO via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 25 05:13:20 PST 2019


Author: higuoxing
Date: Mon Feb 25 05:13:19 2019
New Revision: 354782

URL: http://llvm.org/viewvc/llvm-project?rev=354782&view=rev
Log:
[llvm-objdump] Add `Version References` dumper

Summary: Add symbol version dumper for [#30241](https://bugs.llvm.org/show_bug.cgi?id=30241)

Reviewers: jhenderson, MaskRay, kristina, emaste, grimar

Reviewed By: jhenderson, grimar

Subscribers: grimar, rupprecht, jakehehrlich, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D54697

Added:
    llvm/trunk/test/tools/llvm-objdump/verneed-elf.test
    llvm/trunk/test/tools/llvm-objdump/verneed-wrong-info.test
Modified:
    llvm/trunk/tools/llvm-objdump/ELFDump.cpp
    llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp
    llvm/trunk/tools/llvm-objdump/llvm-objdump.h

Added: llvm/trunk/test/tools/llvm-objdump/verneed-elf.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/verneed-elf.test?rev=354782&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objdump/verneed-elf.test (added)
+++ llvm/trunk/test/tools/llvm-objdump/verneed-elf.test Mon Feb 25 05:13:19 2019
@@ -0,0 +1,47 @@
+# RUN: yaml2obj %s > %t
+# RUN: llvm-objdump -p %t | FileCheck %s
+
+# CHECK:      Version References:
+# CHECK-NEXT:   required from dso.so.0:
+# CHECK-NEXT:     0x000004d2 0x0a 03 v1
+# CHECK-NEXT:     0x0000162e 0x0b 04 v2
+# CHECK-NEXT:   required from dso.so.1:
+# CHECK-NEXT:     0x000011d7 0x0c 02 v3
+
+--- !ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_EXEC
+  Machine:         EM_X86_64
+  Entry:           0x0000000000201000
+Sections:
+  - Name:            .gnu.version_r
+    Type:            SHT_GNU_verneed
+    Flags:           [ SHF_ALLOC ]
+    Address:         0x0000000000200250
+    Link:            .dynstr
+    AddressAlign:    0x0000000000000004
+    Info:            0x0000000000000002
+    Dependencies:
+      - Version:         1
+        File:            dso.so.0
+        Entries:
+          - Name:            v1
+            Hash:            1234
+            Flags:           10
+            Other:           3
+          - Name:            v2
+            Hash:            5678
+            Flags:           11
+            Other:           4
+      - Version:         1
+        File:            dso.so.1
+        Entries:
+          - Name:            v3
+            Hash:            4567
+            Flags:           12
+            Other:           2
+DynamicSymbols:
+  Global:
+    - Name:            f1

Added: llvm/trunk/test/tools/llvm-objdump/verneed-wrong-info.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/verneed-wrong-info.test?rev=354782&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objdump/verneed-wrong-info.test (added)
+++ llvm/trunk/test/tools/llvm-objdump/verneed-wrong-info.test Mon Feb 25 05:13:19 2019
@@ -0,0 +1,50 @@
+# RUN: yaml2obj %s > %t
+# RUN: llvm-objdump -p %t 2>&1 | FileCheck %s
+
+# We have a SHT_GNU_verneed section with a broken sh_info field
+# that says the section contains more entries than it actually has.
+
+# CHECK:      Version References:
+# CHECK-NEXT:   required from dso.so.0:
+# CHECK-NEXT:     0x000004d2 0x0a 03 v1
+# CHECK-NEXT:     0x0000162e 0x0b 04 v2
+# CHECK-NEXT:   required from dso.so.1:
+# CHECK-NEXT:     0x000011d7 0x0c 02 v3
+
+--- !ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_EXEC
+  Machine:         EM_X86_64
+  Entry:           0x0000000000201000
+Sections:
+  - Name:            .gnu.version_r
+    Type:            SHT_GNU_verneed
+    Flags:           [ SHF_ALLOC ]
+    Address:         0x0000000000200250
+    Link:            .dynstr
+    AddressAlign:    0x0000000000000004
+    Info:            0x0000000000009999
+    Dependencies:
+      - Version:         1
+        File:            dso.so.0
+        Entries:
+          - Name:            v1
+            Hash:            1234
+            Flags:           10
+            Other:           3
+          - Name:            v2
+            Hash:            5678
+            Flags:           11
+            Other:           4
+      - Version:         1
+        File:            dso.so.1
+        Entries:
+          - Name:            v3
+            Hash:            4567
+            Flags:           12
+            Other:           2
+DynamicSymbols:
+  Global:
+    - Name:            f1

Modified: llvm/trunk/tools/llvm-objdump/ELFDump.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/ELFDump.cpp?rev=354782&r1=354781&r2=354782&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objdump/ELFDump.cpp (original)
+++ llvm/trunk/tools/llvm-objdump/ELFDump.cpp Mon Feb 25 05:13:19 2019
@@ -267,6 +267,65 @@ template <class ELFT> void printProgramH
   outs() << "\n";
 }
 
+template <class ELFT>
+void printSymbolVersionDependency(ArrayRef<uint8_t> Contents,
+                                  StringRef StrTab) {
+  typedef ELFFile<ELFT> ELFO;
+  typedef typename ELFO::Elf_Verneed Elf_Verneed;
+  typedef typename ELFO::Elf_Vernaux Elf_Vernaux;
+
+  outs() << "Version References:\n";
+
+  const uint8_t *Buf = Contents.data();
+  while (Buf) {
+    const Elf_Verneed *Verneed = reinterpret_cast<const Elf_Verneed *>(Buf);
+    outs() << "  required from "
+           << StringRef(StrTab.drop_front(Verneed->vn_file).data()) << ":\n";
+
+    const uint8_t *BufAux = Buf + Verneed->vn_aux;
+    while (BufAux) {
+      const Elf_Vernaux *Vernaux =
+          reinterpret_cast<const Elf_Vernaux *>(BufAux);
+      outs() << "    "
+             << format("0x%08" PRIx32 " ", (uint32_t)Vernaux->vna_hash)
+             << format("0x%02" PRIx16 " ", (uint16_t)Vernaux->vna_flags)
+             << format("%02" PRIu16 " ", (uint16_t)Vernaux->vna_other)
+             << StringRef(StrTab.drop_front(Vernaux->vna_name).data()) << '\n';
+      BufAux = Vernaux->vna_next ? BufAux + Vernaux->vna_next : nullptr;
+    }
+    Buf = Verneed->vn_next ? Buf + Verneed->vn_next : nullptr;
+  }
+}
+
+template <class ELFT>
+void printSymbolVersionInfo(const ELFFile<ELFT> *Elf, StringRef FileName) {
+  typedef typename ELFT::Shdr Elf_Shdr;
+
+  auto SectionsOrError = Elf->sections();
+  if (!SectionsOrError)
+    report_error(FileName, SectionsOrError.takeError());
+
+  for (const Elf_Shdr &Shdr : *SectionsOrError) {
+    if (Shdr.sh_type != ELF::SHT_GNU_verneed)
+      continue;
+
+    auto ContentsOrError = Elf->getSectionContents(&Shdr);
+    if (!ContentsOrError)
+      report_error(FileName, ContentsOrError.takeError());
+
+    auto StrTabSecOrError = Elf->getSection(Shdr.sh_link);
+    if (!StrTabSecOrError)
+      report_error(FileName, StrTabSecOrError.takeError());
+
+    auto StrTabOrError = Elf->getStringTable(*StrTabSecOrError);
+    if (!StrTabOrError)
+      report_error(FileName, StrTabOrError.takeError());
+
+    printSymbolVersionDependency<ELFT>(*ContentsOrError, *StrTabOrError);
+    // TODO: Implement symbol version definitions dumper.
+  }
+}
+
 void llvm::printELFFileHeader(const object::ObjectFile *Obj) {
   if (const auto *ELFObj = dyn_cast<ELF32LEObjectFile>(Obj))
     printProgramHeaders(ELFObj->getELFFile());
@@ -288,3 +347,14 @@ void llvm::printELFDynamicSection(const
   else if (const auto *ELFObj = dyn_cast<ELF64BEObjectFile>(Obj))
     printDynamicSection(ELFObj->getELFFile(), Obj->getFileName());
 }
+
+void llvm::printELFSymbolVersionInfo(const object::ObjectFile *Obj) {
+  if (const auto *ELFObj = dyn_cast<ELF32LEObjectFile>(Obj))
+    printSymbolVersionInfo(ELFObj->getELFFile(), Obj->getFileName());
+  else if (const auto *ELFObj = dyn_cast<ELF32BEObjectFile>(Obj))
+    printSymbolVersionInfo(ELFObj->getELFFile(), Obj->getFileName());
+  else if (const auto *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj))
+    printSymbolVersionInfo(ELFObj->getELFFile(), Obj->getFileName());
+  else if (const auto *ELFObj = dyn_cast<ELF64BEObjectFile>(Obj))
+    printSymbolVersionInfo(ELFObj->getELFFile(), Obj->getFileName());
+}

Modified: llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp?rev=354782&r1=354781&r2=354782&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp (original)
+++ llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp Mon Feb 25 05:13:19 2019
@@ -1887,7 +1887,9 @@ static void printFaultMaps(const ObjectF
 static void printPrivateFileHeaders(const ObjectFile *O, bool OnlyFirst) {
   if (O->isELF()) {
     printELFFileHeader(O);
-    return printELFDynamicSection(O);
+    printELFDynamicSection(O);
+    printELFSymbolVersionInfo(O);
+    return;
   }
   if (O->isCOFF())
     return printCOFFFileHeader(O);

Modified: llvm/trunk/tools/llvm-objdump/llvm-objdump.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/llvm-objdump.h?rev=354782&r1=354781&r2=354782&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objdump/llvm-objdump.h (original)
+++ llvm/trunk/tools/llvm-objdump/llvm-objdump.h Mon Feb 25 05:13:19 2019
@@ -153,6 +153,7 @@ void printMachOLazyBindTable(object::Mac
 void printMachOWeakBindTable(object::MachOObjectFile *O);
 void printELFFileHeader(const object::ObjectFile *O);
 void printELFDynamicSection(const object::ObjectFile *Obj);
+void printELFSymbolVersionInfo(const object::ObjectFile *Obj);
 void printCOFFFileHeader(const object::ObjectFile *O);
 void printCOFFSymbolTable(const object::COFFImportFile *I);
 void printCOFFSymbolTable(const object::COFFObjectFile *O);




More information about the llvm-commits mailing list