[llvm] 54ef74f - [llvm-readobj/readelf] - Don't fail dumping when unable to read the name of the SHT_DYNSYM section.

Georgii Rymar via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 22 03:12:43 PDT 2020


Author: Georgii Rymar
Date: 2020-07-22T13:11:46+03:00
New Revision: 54ef74f738a2750dcf0dc8f97f84c20eab660394

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

LOG: [llvm-readobj/readelf] - Don't fail dumping when unable to read the name of the SHT_DYNSYM section.

We have an issue currently: we are trying to read the name of the SHT_DYNSYM section
very early and using `unwrapOrError` call for that.

The name is needed only for the GNU output. Because of the current logic, the tool
fails to dump the whole object when something is wrong with the name of the .dynsym section.

This patch delays reading the name and also allows it to be broken.

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

Added: 
    

Modified: 
    llvm/test/tools/llvm-readobj/ELF/dyn-symbols.test
    llvm/tools/llvm-readobj/ELFDumper.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/test/tools/llvm-readobj/ELF/dyn-symbols.test b/llvm/test/tools/llvm-readobj/ELF/dyn-symbols.test
index c4ac2f8325fc..004c1cae7a84 100644
--- a/llvm/test/tools/llvm-readobj/ELF/dyn-symbols.test
+++ b/llvm/test/tools/llvm-readobj/ELF/dyn-symbols.test
@@ -83,14 +83,63 @@ ProgramHeaders:
 # RUN: llvm-readelf --dyn-symbols %t1.so > %t.readelf-dyn-symbols
 # RUN: cmp %t.readelf-dyn-symbols %t.readelf-dyn-syms
 
-## Case 3: Check that we are able to dump the dynamic symbol table even when we have no program headers.
+## Case 3.1: Check that we are able to dump the dynamic symbol table even when we have no program headers.
 ## In this case we find the table by it's type (SHT_DYNSYM) and ignore the DT_SYMTAB value.
 # RUN: yaml2obj --docnum=2 %s -o %t2.so
 # RUN: llvm-readobj %t2.so --dyn-symbols | FileCheck %s --check-prefix=NOPHDRS-LLVM
-# RUN: llvm-readelf %t2.so --dyn-symbols | FileCheck %s --check-prefix=NOPHDRS-GNU
+# RUN: llvm-readelf %t2.so --dyn-symbols | FileCheck %s -DNAME=.dynsym --check-prefix=NOPHDRS-GNU
+
+# NOPHDRS-LLVM:      DynamicSymbols [
+# NOPHDRS-WARN:      warning: '[[FILE]]': unable to get the name of the SHT_DYNSYM section: a section [index 2] has an invalid sh_name (0xffffffff) offset which goes past the end of the section name string table
+# NOPHDRS-LLVM-NEXT:   Symbol {
+# NOPHDRS-LLVM-NEXT:     Name:  (0)
+# NOPHDRS-LLVM-NEXT:     Value: 0x0
+# NOPHDRS-LLVM-NEXT:     Size: 0
+# NOPHDRS-LLVM-NEXT:     Binding: Local (0x0)
+# NOPHDRS-LLVM-NEXT:     Type: None (0x0)
+# NOPHDRS-LLVM-NEXT:     Other: 0
+# NOPHDRS-LLVM-NEXT:     Section: Undefined (0x0)
+# NOPHDRS-LLVM-NEXT:   }
+# NOPHDRS-LLVM-NEXT:   Symbol {
+# NOPHDRS-LLVM-NEXT:     Name: foo (1)
+# NOPHDRS-LLVM-NEXT:     Value: 0x0
+# NOPHDRS-LLVM-NEXT:     Size: 0
+# NOPHDRS-LLVM-NEXT:     Binding: Local (0x0)
+# NOPHDRS-LLVM-NEXT:     Type: None (0x0)
+# NOPHDRS-LLVM-NEXT:     Other: 0
+# NOPHDRS-LLVM-NEXT:     Section: Undefined (0x0)
+# NOPHDRS-LLVM-NEXT:   }
+# NOPHDRS-LLVM-NEXT: ]
+
+# NOPHDRS-GNU:      Symbol table '[[NAME]]' contains 2 entries:
+# NOPHDRS-GNU-NEXT:  Num:    Value          Size Type    Bind   Vis       Ndx Name
+# NOPHDRS-GNU-NEXT:    0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT   UND
+# NOPHDRS-GNU-NEXT:    1: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT   UND foo
 
-# NOPHDRS-LLVM: Name: foo
-# NOPHDRS-GNU:  1: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND foo
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_DYN
+  Machine: EM_X86_64
+Sections:
+  - Name:    .dynamic
+    Type:    SHT_DYNAMIC
+    Entries:
+      - Tag:   DT_SYMTAB
+        Value: 0xffff1234
+      - Tag:   DT_NULL
+        Value: 0
+DynamicSymbols:
+  - Name: foo
+
+## Case 3.2: the same as 3.1, but the sh_name field of the SHT_DYNSYM section is invalid.
+##           Check we are still able to dump symbols.
+# RUN: yaml2obj --docnum=3 %s -o %t2.broken.name
+# RUN: llvm-readobj %t2.broken.name --dyn-symbols 2>&1 | \
+# RUN:   FileCheck %s -DFILE=%t2.broken.name --check-prefixes=NOPHDRS-LLVM,NOPHDRS-WARN
+# RUN: llvm-readelf %t2.broken.name --dyn-symbols 2>&1 | \
+# RUN:   FileCheck %s -DFILE=%t2.broken.name -DNAME="<?>" --check-prefixes=NOPHDRS-GNU,NOPHDRS-WARN
 
 --- !ELF
 FileHeader:
@@ -106,12 +155,15 @@ Sections:
         Value: 0xffff1234
       - Tag:   DT_NULL
         Value: 0
+  - Name:   .dynsym
+    Type:   SHT_DYNSYM
+    ShName: 0xffffffff
 DynamicSymbols:
   - Name: foo
 
 ## Case 4: Check we report a warning when there is no SHT_DYNSYM section and we can't map the DT_SYMTAB value
 ## to an address because of the absence of a corresponding PT_LOAD program header.
-# RUN: yaml2obj --docnum=3 %s -o %t3.so
+# RUN: yaml2obj --docnum=4 %s -o %t3.so
 # RUN: llvm-readobj %t3.so --dyn-symbols 2>&1 | FileCheck %s -DFILE=%t3.so --check-prefixes=NOSHT-DYNSYM,NOSHT-DYNSYM-LLVM
 # RUN: llvm-readelf %t3.so --dyn-symbols 2>&1 | FileCheck %s -DFILE=%t3.so --check-prefix=NOSHT-DYNSYM
 
@@ -140,7 +192,7 @@ DynamicSymbols:
 
 ## Case 5: Check that when we can't map the value of the DT_SYMTAB tag to an address, we report a warning and
 ## use the information in the section header table to locate the dynamic symbol table.
-# RUN: yaml2obj --docnum=4 %s -o %t4.so
+# RUN: yaml2obj --docnum=5 %s -o %t4.so
 # RUN: llvm-readobj %t4.so --dyn-symbols 2>&1 | FileCheck -DFILE=%t4.so %s --check-prefixes=BROKEN-DTSYMTAB,BROKEN-DTSYMTAB-LLVM
 # RUN: llvm-readelf %t4.so --dyn-symbols 2>&1 | FileCheck -DFILE=%t4.so %s --check-prefixes=BROKEN-DTSYMTAB,BROKEN-DTSYMTAB-GNU
 
@@ -172,7 +224,7 @@ ProgramHeaders:
 
 ## Case 6: Check that if we can get the location of the dynamic symbol table using both the DT_SYMTAB value
 ## and the section headers table then we prefer the former and report a warning.
-# RUN: yaml2obj --docnum=5 %s -o %t5.so
+# RUN: yaml2obj --docnum=6 %s -o %t5.so
 # RUN: llvm-readobj %t5.so --dyn-symbols 2>&1 | FileCheck -DFILE=%t5.so %s --check-prefixes=PREFER-DTSYMTAB,PREFER-DTSYMTAB-LLVM
 # RUN: llvm-readelf %t5.so --dyn-symbols 2>&1 | FileCheck -DFILE=%t5.so %s --check-prefixes=PREFER-DTSYMTAB,PREFER-DTSYMTAB-GNU
 
@@ -210,7 +262,7 @@ ProgramHeaders:
 
 ## Case 7: Check how we dump versioned symbols. Use both -V and --dyn-symbols
 ## to check that printed version is consistent.
-# RUN: yaml2obj %s --docnum=6 -o %t6
+# RUN: yaml2obj %s --docnum=7 -o %t6
 # RUN: llvm-readobj -V --dyn-symbols %t6 | FileCheck %s --check-prefix=VERSIONED-LLVM
 # RUN: llvm-readelf -V --dyn-symbols %t6 | FileCheck %s --check-prefix=VERSIONED-GNU
 
@@ -293,15 +345,15 @@ DynamicSymbols:
 
 ## Case 8: Check what we print when:
 ## a) The dynamic symbol table does not exist.
-# RUN: yaml2obj %s --docnum=7 -o %t7
+# RUN: yaml2obj %s --docnum=8 -o %t7
 # RUN: llvm-readobj --dyn-symbols %t7 | FileCheck %s --check-prefix=NO-DYNSYM-LLVM
 # RUN: llvm-readelf --dyn-symbols %t7 | count 0
 ## b) The dynamic symbol table has a size of 0.
-# RUN: yaml2obj %s --docnum=8 -o %t8
+# RUN: yaml2obj %s --docnum=9 -o %t8
 # RUN: llvm-readobj --dyn-symbols %t8 | FileCheck %s --check-prefix=NO-DYNSYM-LLVM
 # RUN: llvm-readelf --dyn-symbols %t8 | count 0
 ## c) The dynamic symbol table only contains the null symbol.
-# RUN: yaml2obj %s --docnum=9 -o %t9
+# RUN: yaml2obj %s --docnum=10 -o %t9
 # RUN: llvm-readobj --dyn-symbols %t9 | FileCheck %s --check-prefix=DYNSYM-EMPTY-LLVM
 # RUN: llvm-readelf --dyn-symbols %t9 | FileCheck %s --check-prefix=DYNSYM-EMPTY-GNU
 
@@ -352,7 +404,7 @@ DynamicSymbols: []
 
 ## Case 9: Check what we print when:
 ## a) The size of the dynamic symbol table is not a multiple of its entry size.
-# RUN: yaml2obj %s --docnum=10 -o %t10
+# RUN: yaml2obj %s --docnum=11 -o %t10
 # RUN: llvm-readobj --dyn-symbols %t10 2>&1 | FileCheck %s -DFILE=%t10 --check-prefix=DYNSYM-SIZE-INVALID1
 # RUN: llvm-readelf --dyn-symbols %t10 2>&1 | FileCheck %s -DFILE=%t10 --check-prefix=DYNSYM-SIZE-INVALID1
 
@@ -362,7 +414,7 @@ DynamicSymbols: []
 ##    information about a location and an entity size of the dynamic symbol table from the section header.
 ##    The code uses sizeof(Elf_Sym) for an entity size, so it can't be incorrect and
 ##    the message printed is a bit shorter.
-# RUN: yaml2obj %s --docnum=11 -o %t11
+# RUN: yaml2obj %s --docnum=12 -o %t11
 # RUN: llvm-readobj --dyn-symbols %t11 2>&1 | FileCheck %s -DFILE=%t11 --check-prefix=DYNSYM-SIZE-INVALID2
 # RUN: llvm-readelf --dyn-symbols %t11 2>&1 | FileCheck %s -DFILE=%t11 --check-prefix=DYNSYM-SIZE-INVALID2
 
@@ -370,10 +422,10 @@ DynamicSymbols: []
 
 ## c) In the case when the DT_SYMENT tag is present, we report when it's value does not match the
 #     value of the symbol size for the platform.
-# RUN: yaml2obj %s -D BITS=32 --docnum=12 -o %t12
+# RUN: yaml2obj %s -D BITS=32 --docnum=13 -o %t12
 # RUN: llvm-readobj --dyn-symbols %t12 2>&1 | FileCheck %s -DFILE=%t12 --check-prefix=DYNSYM-SIZE-INVALID3
 # RUN: llvm-readelf --dyn-symbols %t12 2>&1 | FileCheck %s -DFILE=%t12 --check-prefix=DYNSYM-SIZE-INVALID3
-# RUN: yaml2obj %s -D BITS=64 --docnum=12 -o %t13
+# RUN: yaml2obj %s -D BITS=64 --docnum=13 -o %t13
 # RUN: llvm-readobj --dyn-symbols %t13 2>&1 | FileCheck %s -DFILE=%t13 --check-prefix=DYNSYM-SIZE-INVALID4
 # RUN: llvm-readelf --dyn-symbols %t13 2>&1 | FileCheck %s -DFILE=%t13 --check-prefix=DYNSYM-SIZE-INVALID4
 
@@ -433,7 +485,7 @@ Sections:
 ## Check we report a warning when the DT_STRSZ value is broken so that the dynamic string
 ## table goes past the end of the file. Document we stop dumping symbols and report an error.
 
-# RUN: yaml2obj %s --docnum=13 -o %t14
+# RUN: yaml2obj %s --docnum=14 -o %t14
 # RUN: llvm-readobj --dyn-symbols %t14 2>&1 | \
 # RUN:   FileCheck %s -DFILE=%t14 --check-prefix=DYNSTR-INVALID-LLVM
 # RUN: llvm-readelf --dyn-symbols %t14 2>&1 | \
@@ -513,7 +565,7 @@ ProgramHeaders:
       - Section: .dynamic
 
 ## Check we report a warning when the entry size of the dynamic symbol table is zero.
-# RUN: yaml2obj %s --docnum=14 -o %t15
+# RUN: yaml2obj %s --docnum=15 -o %t15
 # RUN: llvm-readobj --dyn-symbols %t15 2>&1 | FileCheck %s -DFILE=%t15 --check-prefix=DYNSYM-ZERO-ENTSIZE-LLVM
 # RUN: llvm-readelf --dyn-symbols %t15 2>&1 | \
 # RUN:   FileCheck %s -DFILE=%t15 --check-prefix=DYNSYM-ZERO-ENTSIZE-GNU --implicit-check-not="Symbol table"

diff  --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index a21e80d080fd..5569b69f380e 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -292,9 +292,9 @@ template <typename ELFT> class ELFDumper : public ObjDumper {
   const Elf_Hash *HashTable = nullptr;
   const Elf_GnuHash *GnuHashTable = nullptr;
   const Elf_Shdr *DotSymtabSec = nullptr;
+  const Elf_Shdr *DotDynsymSec = nullptr;
   const Elf_Shdr *DotCGProfileSec = nullptr;
   const Elf_Shdr *DotAddrsigSec = nullptr;
-  StringRef DynSymtabName;
   ArrayRef<Elf_Word> ShndxTable;
 
   const Elf_Shdr *SymbolVersionSection = nullptr;   // .gnu.version
@@ -680,7 +680,18 @@ void ELFDumper<ELFT>::printSymbolsHelper(bool IsDynamic) const {
   if (IsDynamic) {
     StrTable = DynamicStringTable;
     Syms = dynamic_symbols();
-    SymtabName = DynSymtabName;
+
+    if (DotDynsymSec) {
+      if (Expected<StringRef> NameOrErr = Obj->getSectionName(DotDynsymSec)) {
+        SymtabName = *NameOrErr;
+      } else {
+        reportUniqueWarning(
+            createError("unable to get the name of the SHT_DYNSYM section: " +
+                        toString(NameOrErr.takeError())));
+        SymtabName = "<?>";
+      }
+    }
+
     Entries = Syms.size();
   } else {
     if (!DotSymtabSec)
@@ -2075,14 +2086,13 @@ ELFDumper<ELFT>::ELFDumper(const object::ELFObjectFile<ELFT> *ObjF,
         DotSymtabSec = &Sec;
       break;
     case ELF::SHT_DYNSYM:
+      if (!DotDynsymSec)
+        DotDynsymSec = &Sec;
+
       if (!DynSymRegion) {
         DynSymRegion = createDRIFrom(&Sec);
         DynSymRegion->Context =
             ("section with index " + Twine(&Sec - &Sections.front())).str();
-        // This is only used (if Elf_Shdr present)for naming section in GNU
-        // style
-        DynSymtabName =
-            unwrapOrError(ObjF->getFileName(), Obj->getSectionName(&Sec));
 
         if (Expected<StringRef> E = Obj->getStringTableForSymtab(Sec))
           DynamicStringTable = *E;


        


More information about the llvm-commits mailing list