[llvm] e19f19b - [llvm-readobj/llvm-readelf] - Simplify the code that dumps versions.

Georgii Rymar via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 2 04:14:54 PST 2019


Author: Georgii Rymar
Date: 2019-12-02T15:14:30+03:00
New Revision: e19f19b09f83b1d64b9513a8f209773d4e21ad15

URL: https://github.com/llvm/llvm-project/commit/e19f19b09f83b1d64b9513a8f209773d4e21ad15
DIFF: https://github.com/llvm/llvm-project/commit/e19f19b09f83b1d64b9513a8f209773d4e21ad15.diff

LOG: [llvm-readobj/llvm-readelf] - Simplify the code that dumps versions.

After changes introduced in D70495 and D70826 its now possible
to significantly simplify the code we have.

This also fixes an issue: previous code assumed that version strings
should always be read from the dynamic string table. While it is
normally true, the string table should be taken from the corresponding
sh_link field.

Differential revision: https://reviews.llvm.org/D70855

Added: 
    

Modified: 
    llvm/test/tools/llvm-readobj/elf-verdef-invalid.test
    llvm/test/tools/llvm-readobj/elf-verneed-invalid.test
    llvm/tools/llvm-readobj/ELFDumper.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/test/tools/llvm-readobj/elf-verdef-invalid.test b/llvm/test/tools/llvm-readobj/elf-verdef-invalid.test
index 65e88119d0e5..253a2179008a 100644
--- a/llvm/test/tools/llvm-readobj/elf-verdef-invalid.test
+++ b/llvm/test/tools/llvm-readobj/elf-verdef-invalid.test
@@ -262,3 +262,48 @@ Sections:
         Names: []
 DynamicSymbols:
   - Name: foo
+
+## Check we error out when trying to print version symbols, but SHT_GNU_verdef is invalid due to any reason.
+
+# RUN: yaml2obj %s --docnum=10 -o %t10
+# RUN: not llvm-readobj -V %t10 2>&1 | FileCheck %s --check-prefix=INVALID-VERDEF-LLVM -DFILE=%t10
+# RUN: not llvm-readelf -V %t10 2>&1 | FileCheck %s --check-prefix=INVALID-VERDEF-GNU -DFILE=%t10
+
+# INVALID-VERDEF-LLVM:      VersionSymbols [
+# INVALID-VERDEF-LLVM-NEXT:    Symbol {
+# INVALID-VERDEF-LLVM-NEXT:      Version: 0
+# INVALID-VERDEF-LLVM-NEXT:      Name:
+# INVALID-VERDEF-LLVM-NEXT:    }
+# INVALID-VERDEF-LLVM-NEXT:    Symbol {
+# INVALID-VERDEF-LLVM-EMPTY:
+# INVALID-VERDEF-LLVM-NEXT:  error: '[[FILE]]': invalid SHT_GNU_verdef section with index 2: version definition 1 goes past the end of the section
+
+# INVALID-VERDEF-GNU:      Version symbols section '.gnu.version' contains 2 entries:
+# INVALID-VERDEF-GNU-NEXT:  Addr: 0000000000000000  Offset: 0x000040  Link: 5 (.dynsym)
+# INVALID-VERDEF-GNU-NEXT:   000:   0 (*local*)
+# INVALID-VERDEF-GNU-NEXT: error: '[[FILE]]': invalid SHT_GNU_verdef section with index 2: version definition 1 goes past the end of the section
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_DYN
+  Machine: EM_X86_64
+Sections:
+  - Name:         .gnu.version
+    Type:         SHT_GNU_versym
+    Flags:        [ SHF_ALLOC ]
+    Link:         .dynsym
+    AddressAlign: 0x0000000000000002
+    EntSize:      0x0000000000000002
+    Entries:      [ 0, 2 ]
+  - Name:         .gnu.version_d
+    Type:         SHT_GNU_verdef
+    Flags:        [ SHF_ALLOC ]
+    Link:         .dynstr
+    AddressAlign: 0x4
+    Info:         0x1
+    Entries: []
+DynamicSymbols:
+  - Name:    foo
+    Binding: STB_GLOBAL

diff  --git a/llvm/test/tools/llvm-readobj/elf-verneed-invalid.test b/llvm/test/tools/llvm-readobj/elf-verneed-invalid.test
index 88039f89c593..81976539bbcb 100644
--- a/llvm/test/tools/llvm-readobj/elf-verneed-invalid.test
+++ b/llvm/test/tools/llvm-readobj/elf-verneed-invalid.test
@@ -86,11 +86,12 @@ DynamicSymbols:
 
 # GNU-NOLINK:      Version symbols section '.gnu.version' contains 2 entries:
 # GNU-NOLINK-NEXT:  Addr: 0000000000000000  Offset: 0x000040  Link: 5 (.dynsym)
-# GNU-NOLINK-NEXT:   000:   0 (*local*)       2 (bar)
+# GNU-NOLINK-NEXT:   000:   0 (*local*)
+# GNU-NOLINK-NEXT: warning: '[[FILE]]': invalid string table linked to SHT_GNU_verneed section with index 2: invalid sh_type for string table section [index 0]: expected SHT_STRTAB, but got SHT_NULL
+# GNU-NOLINK-NEXT:   2 (<corrupt>)
+# GNU-NOLINK-EMPTY:
 # GNU-NOLINK:      Version needs section '.gnu.version_r' contains 1 entries:
 # GNU-NOLINK-NEXT:  Addr: 0000000000000000  Offset: 0x000044  Link: 0 ()
-# GNU-NOLINK-EMPTY:
-# GNU-NOLINK-NEXT:  warning: '[[FILE]]': invalid string table linked to SHT_GNU_verneed section with index 2: invalid sh_type for string table section [index 0]: expected SHT_STRTAB, but got SHT_NULL
 # GNU-NOLINK-NEXT:   0x0000: Version: 1  File: <corrupt vn_file: 9>  Cnt: 1
 # GNU-NOLINK-NEXT:   0x0010:   Name: <corrupt>  Flags: none Version: 2
 
@@ -100,14 +101,14 @@ DynamicSymbols:
 # LLVM-NOLINK-NEXT:     Name:
 # LLVM-NOLINK-NEXT:   }
 # LLVM-NOLINK-NEXT:   Symbol {
+# LLVM-NOLINK-EMPTY:
+# LLVM-NOLINK-NEXT:  warning: '[[FILE]]': invalid string table linked to SHT_GNU_verneed section with index 2: invalid sh_type for string table section [index 0]: expected SHT_STRTAB, but got SHT_NULL
 # LLVM-NOLINK-NEXT:     Version: 2
-# LLVM-NOLINK-NEXT:     Name: foo at bar
+# LLVM-NOLINK-NEXT:     Name: foo@<corrupt>
 # LLVM-NOLINK-NEXT:   }
 # LLVM-NOLINK-NEXT: ]
 
 # LLVM-NOLINK:      VersionRequirements [
-# LLVM-NOLINK-EMPTY:
-# LLVM-NOLINK-NEXT:  warning: '[[FILE]]': invalid string table linked to SHT_GNU_verneed section with index 2: invalid sh_type for string table section [index 0]: expected SHT_STRTAB, but got SHT_NULL
 # LLVM-NOLINK-NEXT:   Dependency {
 # LLVM-NOLINK-NEXT:     Version: 1
 # LLVM-NOLINK-NEXT:     Count: 1
@@ -155,14 +156,12 @@ DynamicSymbols:
     Binding: STB_GLOBAL
 
 ## We can't parse misaligned auxiliary version records.
-## Here we have a SHT_GNU_verneed section aligned by 1 byte.
-## This makes the first auxiliary record offset % 4 be non-zero.
 
 # RUN: yaml2obj --docnum=3 %s -o %t3
 # RUN: not llvm-readelf -V %t3 2>&1 | FileCheck %s -DFILE=%t3 --check-prefix=BROKEN-AUX
 # RUN: not llvm-readobj -V %t3 2>&1 | FileCheck %s -DFILE=%t3 --check-prefix=BROKEN-AUX
 
-# BROKEN-AUX: error: '[[FILE]]': SHT_GNU_verneed: the vn_aux field of the entry with index 0 references a misaligned auxiliary record
+# BROKEN-AUX: error: '[[FILE]]': invalid SHT_GNU_verneed section with index 2: found a misaligned auxiliary entry at offset 0x11
 
 --- !ELF
 FileHeader:
@@ -176,19 +175,14 @@ Sections:
     Flags:   [ SHF_ALLOC ]
     Link:    .dynsym
     Entries: [ 2 ]
-  - Name:  .gnu.version_r
-    Type:  SHT_GNU_verneed
-    Flags: [ SHF_ALLOC ]
-    Info:  1
-    AddressAlign: 1
-    Dependencies:
-      - Version: 1
-        File:    somefile
-        Entries:
-          - Name:  'bar'
-            Hash:  0
-            Flags: 0
-            Other: 2
+  - Name:         .gnu.version_r
+    Type:         SHT_GNU_verneed
+    Flags:        [ SHF_ALLOC ]
+    Info:         1
+    Link:         .dynstr
+    AddressAlign: 4
+## The byte offset to the auxiliary entry is 0x11, i.e. it is not correctly aligned in memory.
+    Content: "0100010001000000110000000000000000000000"
 DynamicSymbols:
   - Name: foo
 
@@ -551,3 +545,63 @@ Sections:
             Other: 0
 DynamicSymbols:
   - Name: foo
+
+## In this case SHT_GNU_verneed is linked to a custom dynamic string table, which is not
+## called ".dynstr". Check we handle this case properly.
+
+# RUN: yaml2obj --docnum=13 %s -o %t13
+# RUN: llvm-readelf -V %t13 2>&1 | FileCheck %s -DFILE=%t13 --check-prefix=GNU-CUSTOM-DYNSTR
+# RUN: llvm-readobj -V %t13 2>&1 | FileCheck %s -DFILE=%t13 --check-prefix=LLVM-CUSTOM-DYNSTR
+
+# GNU-CUSTOM-DYNSTR:      Version symbols section '.gnu.version' contains 2 entries:
+# GNU-CUSTOM-DYNSTR-NEXT:  Addr: 0000000000000000  Offset: 0x000040  Link: 6 (.dynsym)
+# GNU-CUSTOM-DYNSTR-NEXT:   000:   0 (*local*)       2 (bcdefghij)
+# GNU-CUSTOM-DYNSTR:      Version needs section '.gnu.version_r' contains 1 entries:
+# GNU-CUSTOM-DYNSTR-NEXT:  Addr: 0000000000000000  Offset: 0x000044  Link: 3 (.custom.dynstr)
+# GNU-CUSTOM-DYNSTR-NEXT:   0x0000: Version: 1  File: j  Cnt: 1
+# GNU-CUSTOM-DYNSTR-NEXT:   0x0010:   Name: bcdefghij  Flags: none  Version: 2
+
+# LLVM-CUSTOM-DYNSTR:      VersionSymbols [
+# LLVM-CUSTOM-DYNSTR:      Symbol {
+# LLVM-CUSTOM-DYNSTR:        Version: 2
+# LLVM-CUSTOM-DYNSTR-NEXT:   Name: foo at bcdefghij
+
+# LLVM-CUSTOM-DYNSTR:      VersionRequirements [
+# LLVM-CUSTOM-DYNSTR:        Dependency {
+# LLVM-CUSTOM-DYNSTR:          Entries [
+# LLVM-CUSTOM-DYNSTR:            Entry {
+# LLVM-CUSTOM-DYNSTR:              Index: 2
+# LLVM-CUSTOM-DYNSTR-NEXT:          Name: bcdefghij
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_EXEC
+  Machine: EM_X86_64
+Sections:
+  - Name:    .gnu.version
+    Type:    SHT_GNU_versym
+    Flags:   [ SHF_ALLOC ]
+    Link:    .dynsym
+    Entries: [ 0, 2 ]
+  - Name:         .gnu.version_r
+    Type:         SHT_GNU_verneed
+    Flags:        [ SHF_ALLOC ]
+    Link:         .custom.dynstr
+    Info:         1
+    AddressAlign: 4
+    Dependencies:
+      - Version: 1
+        File:    zed
+        Entries:
+          - Name:  'bar'
+            Hash:  0
+            Flags: 0
+            Other: 2
+  - Name: .custom.dynstr
+    Type: SHT_STRTAB
+    Content: "6162636465666768696a00" ## 'a','b','c','d','e','f','g','h','i','j',NIL
+DynamicSymbols:
+  - Name:    foo
+    Binding: STB_GLOBAL

diff  --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index adc3ae7dcc83..8a9fd33c5168 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -258,11 +258,8 @@ template <typename ELFT> class ELFDumper : public ObjDumper {
   void loadDynamicTable(const ELFFile<ELFT> *Obj);
   void parseDynamicTable();
 
-  StringRef getSymbolVersion(StringRef StrTab, const Elf_Sym *symb,
-                             bool &IsDefault) const;
+  StringRef getSymbolVersion(const Elf_Sym *symb, bool &IsDefault) const;
   void LoadVersionMap() const;
-  void LoadVersionNeeds(const Elf_Shdr *ec) const;
-  void LoadVersionDefs(const Elf_Shdr *sec) const;
 
   const object::ELFObjectFile<ELFT> *ObjF;
   DynRegionInfo DynRelRegion;
@@ -285,29 +282,11 @@ template <typename ELFT> class ELFDumper : public ObjDumper {
   const Elf_Shdr *SymbolVersionNeedSection = nullptr; // .gnu.version_r
   const Elf_Shdr *SymbolVersionDefSection = nullptr; // .gnu.version_d
 
-  // Records for each version index the corresponding Verdef or Vernaux entry.
-  // This is filled the first time LoadVersionMap() is called.
-  class VersionMapEntry : public PointerIntPair<const void *, 1> {
-  public:
-    // If the integer is 0, this is an Elf_Verdef*.
-    // If the integer is 1, this is an Elf_Vernaux*.
-    VersionMapEntry() : PointerIntPair<const void *, 1>(nullptr, 0) {}
-    VersionMapEntry(const Elf_Verdef *verdef)
-        : PointerIntPair<const void *, 1>(verdef, 0) {}
-    VersionMapEntry(const Elf_Vernaux *vernaux)
-        : PointerIntPair<const void *, 1>(vernaux, 1) {}
-
-    bool isNull() const { return getPointer() == nullptr; }
-    bool isVerdef() const { return !isNull() && getInt() == 0; }
-    bool isVernaux() const { return !isNull() && getInt() == 1; }
-    const Elf_Verdef *getVerdef() const {
-      return isVerdef() ? (const Elf_Verdef *)getPointer() : nullptr;
-    }
-    const Elf_Vernaux *getVernaux() const {
-      return isVernaux() ? (const Elf_Vernaux *)getPointer() : nullptr;
-    }
+  struct VersionEntry {
+    std::string Name;
+    bool IsVerDef;
   };
-  mutable SmallVector<VersionMapEntry, 16> VersionMap;
+  mutable SmallVector<Optional<VersionEntry>, 16> VersionMap;
 
 public:
   Elf_Dyn_Range dynamic_table() const {
@@ -340,8 +319,7 @@ template <typename ELFT> class ELFDumper : public ObjDumper {
                                            unsigned SectionIndex) const;
   Expected<std::string> getStaticSymbolName(uint32_t Index) const;
   std::string getDynamicString(uint64_t Value) const;
-  StringRef getSymbolVersionByIndex(StringRef StrTab,
-                                    uint32_t VersionSymbolIndex,
+  StringRef getSymbolVersionByIndex(uint32_t VersionSymbolIndex,
                                     bool &IsDefault) const;
 
   void printSymbolsHelper(bool IsDynamic) const;
@@ -909,78 +887,6 @@ std::error_code createELFDumper(const object::ObjectFile *Obj,
 
 } // end namespace llvm
 
-// Iterate through the versions needed section, and place each Elf_Vernaux
-// in the VersionMap according to its index.
-template <class ELFT>
-void ELFDumper<ELFT>::LoadVersionNeeds(const Elf_Shdr *Sec) const {
-  unsigned VerneedSize = Sec->sh_size;    // Size of section in bytes
-  unsigned VerneedEntries = Sec->sh_info; // Number of Verneed entries
-  const uint8_t *VerneedStart = reinterpret_cast<const uint8_t *>(
-      ObjF->getELFFile()->base() + Sec->sh_offset);
-  const uint8_t *VerneedEnd = VerneedStart + VerneedSize;
-  // The first Verneed entry is at the start of the section.
-  const uint8_t *VerneedBuf = VerneedStart;
-  for (unsigned VerneedIndex = 0; VerneedIndex < VerneedEntries;
-       ++VerneedIndex) {
-    if (VerneedBuf + sizeof(Elf_Verneed) > VerneedEnd)
-      report_fatal_error("Section ended unexpectedly while scanning "
-                         "version needed records.");
-    const Elf_Verneed *Verneed =
-        reinterpret_cast<const Elf_Verneed *>(VerneedBuf);
-    if (Verneed->vn_version != ELF::VER_NEED_CURRENT)
-      report_fatal_error("Unexpected verneed version");
-    // Iterate through the Vernaux entries
-    const uint8_t *VernauxBuf = VerneedBuf + Verneed->vn_aux;
-    for (unsigned VernauxIndex = 0; VernauxIndex < Verneed->vn_cnt;
-         ++VernauxIndex) {
-      if (VernauxBuf + sizeof(Elf_Vernaux) > VerneedEnd)
-        report_fatal_error("Section ended unexpected while scanning auxiliary "
-                           "version needed records.");
-      if ((ptr
diff _t)VernauxBuf % sizeof(uint32_t) != 0)
-        reportError(createError("SHT_GNU_verneed: the vn_aux field of the "
-                                "entry with index " +
-                                Twine(VerneedIndex) +
-                                " references a misaligned auxiliary record"),
-                    ObjF->getFileName());
-
-      const Elf_Vernaux *Vernaux =
-          reinterpret_cast<const Elf_Vernaux *>(VernauxBuf);
-      size_t Index = Vernaux->vna_other & ELF::VERSYM_VERSION;
-      if (Index >= VersionMap.size())
-        VersionMap.resize(Index + 1);
-      VersionMap[Index] = VersionMapEntry(Vernaux);
-      VernauxBuf += Vernaux->vna_next;
-    }
-    VerneedBuf += Verneed->vn_next;
-  }
-}
-
-// Iterate through the version definitions, and place each Elf_Verdef
-// in the VersionMap according to its index.
-template <class ELFT>
-void ELFDumper<ELFT>::LoadVersionDefs(const Elf_Shdr *Sec) const {
-  unsigned VerdefSize = Sec->sh_size;    // Size of section in bytes
-  unsigned VerdefEntries = Sec->sh_info; // Number of Verdef entries
-  const uint8_t *VerdefStart = reinterpret_cast<const uint8_t *>(
-      ObjF->getELFFile()->base() + Sec->sh_offset);
-  const uint8_t *VerdefEnd = VerdefStart + VerdefSize;
-  // The first Verdef entry is at the start of the section.
-  const uint8_t *VerdefBuf = VerdefStart;
-  for (unsigned VerdefIndex = 0; VerdefIndex < VerdefEntries; ++VerdefIndex) {
-    if (VerdefBuf + sizeof(Elf_Verdef) > VerdefEnd)
-      report_fatal_error("Section ended unexpectedly while scanning "
-                         "version definitions.");
-    const Elf_Verdef *Verdef = reinterpret_cast<const Elf_Verdef *>(VerdefBuf);
-    if (Verdef->vd_version != ELF::VER_DEF_CURRENT)
-      report_fatal_error("Unexpected verdef version");
-    size_t Index = Verdef->vd_ndx & ELF::VERSYM_VERSION;
-    if (Index >= VersionMap.size())
-      VersionMap.resize(Index + 1);
-    VersionMap[Index] = VersionMapEntry(Verdef);
-    VerdefBuf += Verdef->vd_next;
-  }
-}
-
 template <class ELFT> void ELFDumper<ELFT>::LoadVersionMap() const {
   // If there is no dynamic symtab or version table, there is nothing to do.
   if (!DynSymRegion.Addr || !SymbolVersionSection)
@@ -992,19 +898,37 @@ template <class ELFT> void ELFDumper<ELFT>::LoadVersionMap() const {
 
   // The first two version indexes are reserved.
   // Index 0 is LOCAL, index 1 is GLOBAL.
-  VersionMap.push_back(VersionMapEntry());
-  VersionMap.push_back(VersionMapEntry());
+  VersionMap.push_back(VersionEntry());
+  VersionMap.push_back(VersionEntry());
 
-  if (SymbolVersionDefSection)
-    LoadVersionDefs(SymbolVersionDefSection);
+  auto InsertEntry = [this](unsigned N, StringRef Version, bool IsVerdef) {
+    if (N >= VersionMap.size())
+      VersionMap.resize(N + 1);
+    VersionMap[N] = {Version, IsVerdef};
+  };
 
-  if (SymbolVersionNeedSection)
-    LoadVersionNeeds(SymbolVersionNeedSection);
+  if (SymbolVersionDefSection) {
+    Expected<std::vector<VerDef>> Defs =
+        this->getVersionDefinitions(SymbolVersionDefSection);
+    if (!Defs)
+      reportError(Defs.takeError(), ObjF->getFileName());
+    for (const VerDef &Def : *Defs)
+      InsertEntry(Def.Ndx & ELF::VERSYM_VERSION, Def.Name, true);
+  }
+
+  if (SymbolVersionNeedSection) {
+    Expected<std::vector<VerNeed>> Deps =
+        this->getVersionDependencies(SymbolVersionNeedSection);
+    if (!Deps)
+      reportError(Deps.takeError(), ObjF->getFileName());
+    for (const VerNeed &Dep : *Deps)
+      for (const VernAux &Aux : Dep.AuxV)
+        InsertEntry(Aux.Other & ELF::VERSYM_VERSION, Aux.Name, false);
+  }
 }
 
 template <typename ELFT>
-StringRef ELFDumper<ELFT>::getSymbolVersion(StringRef StrTab,
-                                            const Elf_Sym *Sym,
+StringRef ELFDumper<ELFT>::getSymbolVersion(const Elf_Sym *Sym,
                                             bool &IsDefault) const {
   // This is a dynamic symbol. Look in the GNU symbol version table.
   if (!SymbolVersionSection) {
@@ -1022,7 +946,7 @@ StringRef ELFDumper<ELFT>::getSymbolVersion(StringRef StrTab,
   const Elf_Versym *Versym = unwrapOrError(
       ObjF->getFileName(), ObjF->getELFFile()->template getEntry<Elf_Versym>(
                                SymbolVersionSection, EntryIndex));
-  return this->getSymbolVersionByIndex(StrTab, Versym->vs_index, IsDefault);
+  return this->getSymbolVersionByIndex(Versym->vs_index, IsDefault);
 }
 
 static std::string maybeDemangle(StringRef Name) {
@@ -1049,8 +973,7 @@ ELFDumper<ELFT>::getStaticSymbolName(uint32_t Index) const {
 }
 
 template <typename ELFT>
-StringRef ELFDumper<ELFT>::getSymbolVersionByIndex(StringRef StrTab,
-                                                   uint32_t SymbolVersionIndex,
+StringRef ELFDumper<ELFT>::getSymbolVersionByIndex(uint32_t SymbolVersionIndex,
                                                    bool &IsDefault) const {
   size_t VersionIndex = SymbolVersionIndex & VERSYM_VERSION;
 
@@ -1062,23 +985,15 @@ StringRef ELFDumper<ELFT>::getSymbolVersionByIndex(StringRef StrTab,
 
   // Lookup this symbol in the version table.
   LoadVersionMap();
-  if (VersionIndex >= VersionMap.size() || VersionMap[VersionIndex].isNull())
+  if (VersionIndex >= VersionMap.size() || !VersionMap[VersionIndex])
     reportError(createError("Invalid version entry"), ObjF->getFileName());
-  const VersionMapEntry &Entry = VersionMap[VersionIndex];
 
-  // Get the version name string.
-  size_t NameOffset;
-  if (Entry.isVerdef()) {
-    // The first Verdaux entry holds the name.
-    NameOffset = Entry.getVerdef()->getAux()->vda_name;
+  const VersionEntry &Entry = *VersionMap[VersionIndex];
+  if (Entry.IsVerDef)
     IsDefault = !(SymbolVersionIndex & VERSYM_HIDDEN);
-  } else {
-    NameOffset = Entry.getVernaux()->vna_name;
+  else
     IsDefault = false;
-  }
-  if (NameOffset >= StrTab.size())
-    reportError(createError("Invalid string offset"), ObjF->getFileName());
-  return StrTab.data() + NameOffset;
+  return Entry.Name.c_str();
 }
 
 template <typename ELFT>
@@ -1109,7 +1024,7 @@ std::string ELFDumper<ELFT>::getFullSymbolName(const Elf_Sym *Symbol,
     return SymbolName;
 
   bool IsDefault;
-  StringRef Version = getSymbolVersion(StrTable, &*Symbol, IsDefault);
+  StringRef Version = getSymbolVersion(&*Symbol, IsDefault);
   if (!Version.empty()) {
     SymbolName += (IsDefault ? "@@" : "@");
     SymbolName += Version;
@@ -4100,7 +4015,6 @@ void GNUStyle<ELFT>::printVersionSymbolSection(const ELFFile<ELFT> *Obj,
   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) {
@@ -4119,17 +4033,17 @@ void GNUStyle<ELFT>::printVersionSymbolSection(const ELFFile<ELFT> *Obj,
         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);
+        std::string VersionName =
+            Dumper->getSymbolVersionByIndex(Versym->vs_index, IsDefault);
 
         if (!VersionName.empty())
           VersionName = "(" + VersionName + ")";
         else
           VersionName = "(*invalid*)";
+
+        OS << format("%4x%c", Versym->vs_index & VERSYM_VERSION,
+                     Versym->vs_index & VERSYM_HIDDEN ? 'h' : ' ');
         OS << left_justify(VersionName, 13);
       }
       VersymBuf += sizeof(Elf_Versym);


        


More information about the llvm-commits mailing list