[llvm] r357578 - [llvm-readobj] Add GNU style dumper for .gnu.version section

Xing GUO via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 3 06:32:49 PDT 2019


Author: higuoxing
Date: Wed Apr  3 06:32:49 2019
New Revision: 357578

URL: http://llvm.org/viewvc/llvm-project?rev=357578&view=rev
Log:
[llvm-readobj] Add GNU style dumper for .gnu.version section

Summary: Currently, `llvm-readobj` do not support GNU style dumper for symbol versioning sections. In this patch, I would like to implement dumper for `.gnu.version` section

Reviewers: jhenderson, rupprecht, grimar

Reviewed By: jhenderson, rupprecht

Subscribers: llvm-commits

Tags: #llvm

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

Added:
    llvm/trunk/test/tools/llvm-readobj/elf-hidden-versym.test
    llvm/trunk/test/tools/llvm-readobj/elf-invalid-versioning.test
Modified:
    llvm/trunk/test/tools/llvm-readobj/elf-versioninfo.test
    llvm/trunk/tools/llvm-readobj/ELFDumper.cpp

Added: llvm/trunk/test/tools/llvm-readobj/elf-hidden-versym.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/elf-hidden-versym.test?rev=357578&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-readobj/elf-hidden-versym.test (added)
+++ llvm/trunk/test/tools/llvm-readobj/elf-hidden-versym.test Wed Apr  3 06:32:49 2019
@@ -0,0 +1,42 @@
+# RUN: yaml2obj %s -o %t
+# RUN: llvm-readelf -V %t | FileCheck %s --check-prefix=HIDDEN
+
+# HIDDEN:      Version symbols section '.gnu.version' contains 2 entries:
+# HIDDEN-NEXT:  Addr: 0000000000200210  Offset: 0x000240  Link: 6 (.dynsym)
+# HIDDEN-NEXT:   000:   0 (*local*)       3h(hiddensym)
+
+--- !ELF
+FileHeader:
+  Class:             ELFCLASS64
+  Data:              ELFDATA2LSB
+  Type:              ET_EXEC
+  Machine:           EM_X86_64
+  Entry:             0x0000000000201000
+Sections:
+  - Name:            .gnu.version
+    Type:            SHT_GNU_versym
+    Flags:           [ SHF_ALLOC ]
+    Address:         0x0000000000200210
+    Link:            .dynsym
+    AddressAlign:    0x0000000000000002
+    EntSize:         0x0000000000000002
+    Entries:         [ 0, 0x8003 ]
+  - Name:            .gnu.version_r
+    Type:            SHT_GNU_verneed
+    Flags:           [ SHF_ALLOC ]
+    Address:         0x0000000000200250
+    Link:            .dynstr
+    AddressAlign:    0x0000000000000004
+    Info:            0x0000000000000001
+    Dependencies:
+      - Version:     1
+        File:        somefile
+        Entries:
+          - Name:    hiddensym
+            Hash:    1234
+            Flags:   0
+            Other:   3
+DynamicSymbols:
+  Global:
+    - Name:          h
+...

Added: llvm/trunk/test/tools/llvm-readobj/elf-invalid-versioning.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/elf-invalid-versioning.test?rev=357578&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-readobj/elf-invalid-versioning.test (added)
+++ llvm/trunk/test/tools/llvm-readobj/elf-invalid-versioning.test Wed Apr  3 06:32:49 2019
@@ -0,0 +1,42 @@
+# RUN: yaml2obj %s -o %t
+# RUN: llvm-readelf -V %t | FileCheck %s --check-prefix=INVALID
+
+# INVALID:      Version symbols section '.gnu.version' contains 2 entries:
+# INVALID-NEXT:  Addr: 0000000000200210  Offset: 0x000240  Link: 6 (.dynsym)
+# INVALID-NEXT:   000:   0 (*local*)       3 (*invalid*)
+
+--- !ELF
+FileHeader:
+  Class:             ELFCLASS64
+  Data:              ELFDATA2LSB
+  Type:              ET_EXEC
+  Machine:           EM_X86_64
+  Entry:             0x0000000000201000
+Sections:
+  - Name:            .gnu.version
+    Type:            SHT_GNU_versym
+    Flags:           [ SHF_ALLOC ]
+    Address:         0x0000000000200210
+    Link:            .dynsym
+    AddressAlign:    0x0000000000000002
+    EntSize:         0x0000000000000002
+    Entries:         [ 0, 3 ]
+  - Name:            .gnu.version_r
+    Type:            SHT_GNU_verneed
+    Flags:           [ SHF_ALLOC ]
+    Address:         0x0000000000200250
+    Link:            .dynstr
+    AddressAlign:    0x0000000000000004
+    Info:            0x0000000000000001
+    Dependencies:
+      - Version:     1
+        File:        somefile
+        Entries:
+          - Name:    ''         # invalid name
+            Hash:    1937
+            Flags:   233
+            Other:   3
+DynamicSymbols:
+  Global:
+    - Name:          f
+...

Modified: llvm/trunk/test/tools/llvm-readobj/elf-versioninfo.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/elf-versioninfo.test?rev=357578&r1=357577&r2=357578&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-readobj/elf-versioninfo.test (original)
+++ llvm/trunk/test/tools/llvm-readobj/elf-versioninfo.test Wed Apr  3 06:32:49 2019
@@ -77,7 +77,11 @@ GNU-VERDEF: 0x000000006ffffff0 VERSYM
 GNU-VERDEF: 0x000000006ffffffc VERDEF               0x25c
 GNU-VERDEF: 0x000000006ffffffd VERDEFNUM            3
 
-GNU-VERDEF: Dumper for .gnu.version is not implemented
+GNU-VERDEF:      Version symbols section '.gnu.version' contains 8 entries:
+GNU-VERDEF-NEXT:  Addr: 000000000000024c  Offset: 0x00024c  Link: 1 (.dynsym)
+GNU-VERDEF-NEXT:   000:   0 (*local*)       1 (*global*)      1 (*global*)      3 (VERSION2)
+GNU-VERDEF-NEXT:   004:   1 (*global*)      2 (VERSION1)      2 (VERSION1)      3 (VERSION2)
+
 GNU-VERDEF: Dumper for .gnu.version_d is not implemented
 
 RUN: llvm-readobj -V %p/Inputs/verneed.elf-x86-64 | FileCheck %s --check-prefix=LLVM-VERNEED
@@ -114,6 +118,9 @@ LLVM-VERNEED-NEXT:     }
 LLVM-VERNEED-NEXT:   }
 LLVM-VERNEED-NEXT: }
 
-GNU-VERNEED: Dumper for .gnu.version is not implemented
+GNU-VERNEED:      Version symbols section '.gnu.version' contains 4 entries:
+GNU-VERNEED-NEXT:  Addr: 0000000000010228  Offset: 0x000228  Link: 1 (.dynsym)
+GNU-VERNEED-NEXT:   000:   0 (*local*)       2 (v3)            3 (v2)            4 (v1)
+
 GNU-VERNEED: Dumper for .gnu.version_r is not implemented
 

Modified: llvm/trunk/tools/llvm-readobj/ELFDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/ELFDumper.cpp?rev=357578&r1=357577&r2=357578&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/ELFDumper.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/ELFDumper.cpp Wed Apr  3 06:32:49 2019
@@ -3355,7 +3355,57 @@ void GNUStyle<ELFT>::printVersionSymbolS
     return;
 
   StringRef SecName = unwrapOrError(Obj->getSectionName(Sec));
-  OS << "Dumper for " << SecName << " is not implemented\n";
+  uint64_t Entries = Sec->sh_size / sizeof(Elf_Versym);
+
+  OS << "Version symbols section '" << SecName << "' "
+     << "contains " << Entries << " entries:\n";
+
+  const Elf_Shdr *SymTab = unwrapOrError(Obj->getSection(Sec->sh_link));
+  StringRef SymTabName = unwrapOrError(Obj->getSectionName(SymTab));
+  OS << " Addr: " << format_hex_no_prefix(Sec->sh_addr, 16)
+     << "  Offset: " << format_hex(Sec->sh_offset, 8)
+     << "  Link: " << Sec->sh_link << " (" << SymTabName << ")\n";
+
+  const uint8_t *VersymBuf =
+      reinterpret_cast<const uint8_t *>(Obj->base() + Sec->sh_offset);
+  const ELFDumper<ELFT> *Dumper = this->dumper();
+  StringRef StrTable = Dumper->getDynamicStringTable();
+
+  // readelf prints 4 entries per line.
+  for (uint64_t VersymRow = 0; VersymRow < Entries; VersymRow += 4) {
+    OS << "  " << format_hex_no_prefix(VersymRow, 3) << ":";
+
+    for (uint64_t VersymIndex = 0;
+         (VersymIndex < 4) && (VersymIndex + VersymRow) < Entries;
+         ++VersymIndex) {
+      const Elf_Versym *Versym =
+          reinterpret_cast<const Elf_Versym *>(VersymBuf);
+      switch (Versym->vs_index) {
+      case 0:
+        OS << "   0 (*local*)    ";
+        break;
+      case 1:
+        OS << "   1 (*global*)   ";
+        break;
+      default:
+        OS << format("%4x%c", Versym->vs_index & VERSYM_VERSION,
+                     Versym->vs_index & VERSYM_HIDDEN ? 'h' : ' ');
+
+        bool IsDefault = true;
+        std::string VersionName = Dumper->getSymbolVersionByIndex(
+            StrTable, Versym->vs_index, IsDefault);
+
+        if (!VersionName.empty())
+          VersionName = "(" + VersionName + ")";
+        else
+          VersionName = "(*invalid*)";
+        OS << left_justify(VersionName, 13);
+      }
+      VersymBuf += sizeof(Elf_Versym);
+    }
+    OS << '\n';
+  }
+  OS << '\n';
 }
 
 template <class ELFT>




More information about the llvm-commits mailing list