[PATCH] D81928: [llvm-readobj] - Split the printGnuHashTable(). NFCI.

George Rimar via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 16 04:58:23 PDT 2020


grimar created this revision.
grimar added reviewers: jhenderson, MaskRay.
Herald added a subscriber: rupprecht.
Herald added a project: LLVM.
grimar edited the summary of this revision.

`printGnuHashTable` contains the code to check the GNU hash table.
This patch splits it to `getGnuHashTableChains` helper (and reorders slightly to reduce).

I am planning to reuse it from the `printGnuHashHistogram()` for
the same purpose.

Also there is a one possible crash issue in this code,
that needs adding a bit more code to it to fix (i.e. it is better to
split it out as it is becoming large).


https://reviews.llvm.org/D81928

Files:
  llvm/tools/llvm-readobj/ELFDumper.cpp


Index: llvm/tools/llvm-readobj/ELFDumper.cpp
===================================================================
--- llvm/tools/llvm-readobj/ELFDumper.cpp
+++ llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -2713,6 +2713,35 @@
   W.printList("Chains", HashTable->chains());
 }
 
+template <class ELFT>
+static Expected<ArrayRef<typename ELFT::Word>>
+getGnuHashTableChains(const typename ELFT::SymRange DynSymTable,
+                      const typename ELFT::GnuHash *GnuHashTable) {
+  size_t NumSyms = DynSymTable.size();
+  if (!NumSyms)
+    return createError("unable to dump 'Values' for the SHT_GNU_HASH "
+                       "section: the dynamic symbol table is empty");
+
+  if (GnuHashTable->symndx < NumSyms)
+    return GnuHashTable->values(NumSyms);
+
+  // A normal empty GNU hash table section produced by linker might have
+  // symndx set to the number of dynamic symbols + 1 (for the zero symbol)
+  // and have dummy null values in the Bloom filter and in the buckets
+  // vector. It happens because the value of symndx is not important for
+  // dynamic loaders when the GNU hash table is empty. They just skip the
+  // whole object during symbol lookup. In such cases, the symndx value is
+  // irrelevant and we should not report a warning.
+  ArrayRef<typename ELFT::Word> Buckets = GnuHashTable->buckets();
+  if (!llvm::all_of(Buckets, [](typename ELFT::Word V) { return V == 0; }))
+    return createError("the first hashed symbol index (" +
+                       Twine(GnuHashTable->symndx) +
+                       ") is larger than the number of dynamic symbols (" +
+                       Twine(NumSyms) + ")");
+
+  return GnuHashTable->values(NumSyms);
+}
+
 template <typename ELFT>
 void ELFDumper<ELFT>::printGnuHashTable(const object::ObjectFile *Obj) {
   DictScope D(W, "GnuHashTable");
@@ -2747,37 +2776,14 @@
     return;
   }
 
-  size_t NumSyms = dynamic_symbols().size();
-  if (!NumSyms) {
-    reportWarning(createError("unable to dump 'Values' for the SHT_GNU_HASH "
-                              "section: the dynamic symbol table is empty"),
-                  ObjF->getFileName());
+  Expected<ArrayRef<Elf_Word>> Chains =
+      getGnuHashTableChains<ELFT>(dynamic_symbols(), GnuHashTable);
+  if (!Chains) {
+    reportWarning(Chains.takeError(), ObjF->getFileName());
     return;
   }
 
-  if (GnuHashTable->symndx >= NumSyms) {
-    // A normal empty GNU hash table section produced by linker might have
-    // symndx set to the number of dynamic symbols + 1 (for the zero symbol)
-    // and have dummy null values in the Bloom filter and in the buckets
-    // vector. It happens because the value of symndx is not important for
-    // dynamic loaders when the GNU hash table is empty. They just skip the
-    // whole object during symbol lookup. In such cases, the symndx value is
-    // irrelevant and we should not report a warning.
-    bool IsEmptyHashTable =
-        llvm::all_of(Buckets, [](Elf_Word V) { return V == 0; });
-
-    if (!IsEmptyHashTable) {
-      reportWarning(
-          createError("the first hashed symbol index (" +
-                      Twine(GnuHashTable->symndx) +
-                      ") is larger than the number of dynamic symbols (" +
-                      Twine(NumSyms) + ")"),
-          ObjF->getFileName());
-      return;
-    }
-  }
-
-  W.printHexList("Values", GnuHashTable->values(NumSyms));
+  W.printHexList("Values", *Chains);
 }
 
 template <typename ELFT> void ELFDumper<ELFT>::printLoadName() {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D81928.271044.patch
Type: text/x-patch
Size: 3517 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200616/19b6b238/attachment.bin>


More information about the llvm-commits mailing list