[llvm-readobj] - Don't crash when checking the number of dynamic symbols.
authorGeorgii Rymar <grimar@accesssoftek.com>
Tue, 30 Jun 2020 14:14:45 +0000 (17:14 +0300)
committerGeorgii Rymar <grimar@accesssoftek.com>
Wed, 1 Jul 2020 09:14:10 +0000 (12:14 +0300)
When we deriving the number of symbols from the DT_HASH table, we can crash when
calculate the number of symbols in the symbol table when SHT_DYNSYM
has sh_entsize == 0.

The patch fixes the issue.

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

llvm/test/tools/llvm-readobj/ELF/dyn-symbols-size-from-hash-table.test
llvm/tools/llvm-readobj/ELFDumper.cpp

index 80cb8e3..7da8059 100644 (file)
@@ -158,6 +158,20 @@ ProgramHeaders:
 # RUN:   FileCheck %s --check-prefixes=GNU2,GNU2-MORE,GNU2-ALL,WARN \
 # RUN:                --implicit-check-not=warning: -DNCHAIN=4
 
+# WARN: warning: '{{.*}}2-{{.*}}': hash table nchain ([[NCHAIN]]) differs from symbol count derived from SHT_DYNSYM section header (3)
+
+## Show we report a warning when the sh_entsize of the SHT_DYNSYM section is zero and therefore we are unable
+## to derive the number of dynamic symbols from SHT_DYNSYM section header.
+# RUN: yaml2obj --docnum=2 %s -o %t2-zero-entsize -DCHAIN="[1, 2, 3, 4]" -DENTSIZE=0
+# RUN: llvm-readobj --dyn-symbols %t2-zero-entsize 2>&1 | \
+# RUN:   FileCheck %s -DFILE=%t2-zero-entsize --check-prefixes=LLVM2,LLVM2-MORE,LLVM2-ALL,WARN-ENTSIZE \
+# RUN:                --implicit-check-not=warning:
+# RUN: llvm-readelf --dyn-symbols %t2-zero-entsize 2>&1 | \
+# RUN:   FileCheck %s -DFILE=%t2-zero-entsize --check-prefixes=GNU2,GNU2-MORE,GNU2-ALL,WARN-ENTSIZE \
+# RUN:                --implicit-check-not=warning: -DNCHAIN=4
+
+## WARN-ENTSIZE: warning: '[[FILE]]': SHT_DYNSYM section has sh_entsize == 0
+
 ## Show there's no warning if the sizes match
 # RUN: yaml2obj --docnum=2 %s -o %t2-same -DCHAIN="[1, 2, 3]"
 # RUN: llvm-readobj --dyn-symbols %t2-same 2>&1 | \
@@ -166,8 +180,6 @@ ProgramHeaders:
 # RUN:   FileCheck %s --check-prefixes=GNU2,GNU2-MORE \
 # RUN:                --implicit-check-not=warning: -DNCHAIN=3
 
-# WARN: warning: '{{.*}}2-{{.*}}': hash table nchain ([[NCHAIN]]) differs from symbol count derived from SHT_DYNSYM section header (3)
-
 # LLVM2:           DynamicSymbols [
 # LLVM2-NEXT:        Symbol {
 # LLVM2-NEXT:          Name:  (0)
@@ -236,6 +248,8 @@ Sections:
     ShSize:       0x48
     Address:      0x400
     AddressAlign: 0x400
+## 0x18 is the standard entsize value.
+    EntSize:      [[ENTSIZE=0x18]]
   - Name:         .hash
     Type:         SHT_HASH
     Flags:        [ SHF_ALLOC ]
index 3f29c99..0fbaf7d 100644 (file)
@@ -2215,13 +2215,17 @@ void ELFDumper<ELFT>::parseDynamicTable(const ELFFile<ELFT> *Obj) {
     // equal nchain". Check to see if the DT_HASH hash table nchain value
     // conflicts with the number of symbols in the dynamic symbol table
     // according to the section header.
-    if (HashTable &&
-        HashTable->nchain != DynSymRegion->Size / DynSymRegion->EntSize)
-      reportUniqueWarning(createError(
-          "hash table nchain (" + Twine(HashTable->nchain) +
-          ") differs from symbol count derived from SHT_DYNSYM section "
-          "header (" +
-          Twine(DynSymRegion->Size / DynSymRegion->EntSize) + ")"));
+    if (HashTable) {
+      if (DynSymRegion->EntSize == 0)
+        reportUniqueWarning(
+            createError("SHT_DYNSYM section has sh_entsize == 0"));
+      else if (HashTable->nchain != DynSymRegion->Size / DynSymRegion->EntSize)
+        reportUniqueWarning(createError(
+            "hash table nchain (" + Twine(HashTable->nchain) +
+            ") differs from symbol count derived from SHT_DYNSYM section "
+            "header (" +
+            Twine(DynSymRegion->Size / DynSymRegion->EntSize) + ")"));
+    }
   }
 
   // Delay the creation of the actual dynamic symbol table until now, so that