[llvm] 6b74eab - [llvm-readelf/obj] - Refine the implementation of `printGNUVersionSectionProlog`

Georgii Rymar via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 24 01:08:32 PST 2020


Author: Georgii Rymar
Date: 2020-11-24T11:56:22+03:00
New Revision: 6b74eabfddbc6629adbf6358f8e78893c4ee1d12

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

LOG: [llvm-readelf/obj] - Refine the implementation of `printGNUVersionSectionProlog`

This:
1) Changes its signature.
2) Refines the name of local variable (`SymTabName`->`LinkedSecName`,
   because SHT_GNU_verneed/SHT_GNU_verdef are linked with the string table, not with the symbol table).
3) Stops using the `unwrapOrError` inside.

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

Added: 
    

Modified: 
    llvm/test/tools/llvm-readobj/ELF/verdef-invalid.test
    llvm/test/tools/llvm-readobj/ELF/verneed-invalid.test
    llvm/test/tools/llvm-readobj/ELF/versym-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 fc4e691f812f..aa9b7b86e227 100644
--- a/llvm/test/tools/llvm-readobj/ELF/verdef-invalid.test
+++ b/llvm/test/tools/llvm-readobj/ELF/verdef-invalid.test
@@ -34,11 +34,11 @@ Sections:
 
 ## Check that we report a warning when we can't read the content of the SHT_GNU_verdef section.
 
-# RUN: yaml2obj %s --docnum=2 -o %t3
+# RUN: yaml2obj %s --docnum=2 -DSHOFFSET=0xFFFFFFFF -o %t3
 # RUN: llvm-readobj -V %t3 2>&1 | FileCheck %s --check-prefix=INVALID-DATA -DFILE=%t3
 # RUN: llvm-readelf -V %t3 2>&1 | FileCheck %s --check-prefix=INVALID-DATA -DFILE=%t3
 
-# INVALID-DATA: warning: '[[FILE]]': cannot read content of SHT_GNU_verdef section with index 1: section [index 1] has a sh_offset (0xffffffff) + sh_size (0x0) that is greater than the file size (0x228)
+# INVALID-DATA: warning: '[[FILE]]': cannot read content of SHT_GNU_verdef section with index 1: section [index 1] has a sh_offset (0xffffffff) + sh_size (0x0) that is greater than the file size (0x230)
 
 --- !ELF
 FileHeader:
@@ -51,10 +51,42 @@ Sections:
     Link:     .dynstr
     Info:     0x0
     Entries:  []
-    ShOffset: 0xFFFFFFFF
+    ShOffset: [[SHOFFSET=<none>]]
+    ShName:   [[SHNAME=<none>]]
+  - Name:   .dynstr
+    Type:   SHT_STRTAB
+    ShName: [[DYNSTRNAME=<none>]]
 DynamicSymbols:
   - Name: foo
 
+## Check that llvm-readelf reports a warning when the name of the SHT_GNU_verdef section can't be read.
+
+# RUN: yaml2obj %s --docnum=2 -DSHNAME=0xFF -o %t.invalid.name
+# RUN: llvm-readobj -V %t.invalid.name 2>&1 | \
+# RUN:   FileCheck %s --check-prefix=INVALID-NAME-LLVM -DFILE=%t.invalid.name --implicit-check-not=warning:
+# RUN: llvm-readelf -V %t.invalid.name 2>&1 | \
+# RUN:   FileCheck %s --check-prefix=INVALID-NAME-GNU -DFILE=%t.invalid.name --implicit-check-not=warning:
+
+# INVALID-NAME-LLVM:      VersionDefinitions [
+# INVALID-NAME-LLVM-NEXT: ]
+
+# INVALID-NAME-GNU:      warning: '[[FILE]]': unable to get the name of SHT_GNU_verdef section with index 1: a section [index 1] has an invalid sh_name (0xff) offset which goes past the end of the section name string table
+# INVALID-NAME-GNU-NEXT: Version definition section '<?>' contains 0 entries:
+# INVALID-NAME-GNU-NEXT:  Addr: 0000000000000000  Offset: 0x000040  Link: 2 (.dynstr)
+
+## Check that llvm-readelf reports a warning when we are unable to read the name of
+## the section linked with the SHT_GNU_verdef section (usually ".dynstr").
+
+# RUN: yaml2obj %s --docnum=2 -DDYNSTRNAME=0xFF -o %t.invalid.name2
+# RUN: llvm-readobj -V %t.invalid.name2 2>&1 | \
+# RUN:   FileCheck %s --check-prefix=INVALID-NAME-LLVM -DFILE=%t.invalid.name2 --implicit-check-not=warning:
+# RUN: llvm-readelf -V %t.invalid.name2 2>&1 | \
+# RUN:   FileCheck %s --check-prefix=INVALID-NAME2-GNU -DFILE=%t.invalid.name2 --implicit-check-not=warning:
+
+# INVALID-NAME2-GNU:      Version definition section '.gnu.version_d' contains 0 entries:
+# INVALID-NAME2-GNU-NEXT: warning: '[[FILE]]': unable to get the name of SHT_STRTAB section with index 2: a section [index 2] has an invalid sh_name (0xff) offset which goes past the end of the section name string table
+# INVALID-NAME2-GNU-NEXT:  Addr: 0000000000000000  Offset: 0x000040  Link: 2 (<?>)
+
 ## Check that we report a warning when a SHT_GNU_verdef section contains a version definition
 ## that goes past the end of the section.
 

diff  --git a/llvm/test/tools/llvm-readobj/ELF/verneed-invalid.test b/llvm/test/tools/llvm-readobj/ELF/verneed-invalid.test
index 3bb439b3db91..712bdc4c2434 100644
--- a/llvm/test/tools/llvm-readobj/ELF/verneed-invalid.test
+++ b/llvm/test/tools/llvm-readobj/ELF/verneed-invalid.test
@@ -315,7 +315,7 @@ DynamicSymbols:
 
 ## Check that we report a warning when sh_link references a non-existent section.
 
-# RUN: yaml2obj --docnum=6 %s -o %t6
+# RUN: yaml2obj --docnum=6 %s -DLINK=0xFF -o %t6
 # RUN: llvm-readobj --sections -V %t6 2>&1 | FileCheck %s -DFILE=%t6 --implicit-check-not="warning:" --check-prefix=INVALID-LINK-LLVM
 # RUN: llvm-readelf --sections -V %t6 2>&1 | FileCheck %s -DFILE=%t6 --implicit-check-not="warning:" --check-prefix=INVALID-LINK-GNU
 
@@ -349,11 +349,12 @@ FileHeader:
   Data:  ELFDATA2LSB
   Type:  ET_EXEC
 Sections:
-  - Name:  .gnu.version_r
-    Type:  SHT_GNU_verneed
-    Flags: [ SHF_ALLOC ]
-    Info:  1
-    Link:  0xFF
+  - Name:   .gnu.version_r
+    Type:   SHT_GNU_verneed
+    Flags:  [ SHF_ALLOC ]
+    Info:   1
+    Link:   [[LINK=.dynstr]]
+    ShName: [[SHNAME=<none>]]
     Dependencies:
       - Version: 1
         File:    foo
@@ -362,9 +363,58 @@ Sections:
             Hash:  0
             Flags: 0
             Other: 0
+  - Name:   .dynstr
+    Type:   SHT_STRTAB
+    ShName: [[DYNSTRNAME=<none>]]
 DynamicSymbols:
   - Name: foo
 
+## Check that llvm-readelf reports a warning when the name of the SHT_GNU_verneed section can't be read.
+
+# RUN: yaml2obj --docnum=6 %s -DSHNAME=0xFFFFFFFF -o %t.invalid.name
+# RUN: llvm-readobj -V %t.invalid.name 2>&1 | \
+# RUN:   FileCheck %s -DFILE=%t.invalid.name --check-prefix=INVALID-NAME-LLVM --implicit-check-not=warning:
+# RUN: llvm-readelf -V %t.invalid.name 2>&1 | \
+# RUN:   FileCheck %s -DFILE=%t.invalid.name --check-prefix=INVALID-NAME-GNU --implicit-check-not=warning:
+
+# INVALID-NAME-LLVM:      VersionRequirements [
+# INVALID-NAME-LLVM-NEXT:   Dependency {
+# INVALID-NAME-LLVM-NEXT:     Version: 1
+# INVALID-NAME-LLVM-NEXT:     Count: 1
+# INVALID-NAME-LLVM-NEXT:     FileName: foo
+# INVALID-NAME-LLVM-NEXT:     Entries [
+# INVALID-NAME-LLVM-NEXT:       Entry {
+# INVALID-NAME-LLVM-NEXT:         Hash: 0
+# INVALID-NAME-LLVM-NEXT:         Flags [ (0x0)
+# INVALID-NAME-LLVM-NEXT:         ]
+# INVALID-NAME-LLVM-NEXT:         Index: 0
+# INVALID-NAME-LLVM-NEXT:         Name: foo
+# INVALID-NAME-LLVM-NEXT:       }
+# INVALID-NAME-LLVM-NEXT:     ]
+# INVALID-NAME-LLVM-NEXT:   }
+# INVALID-NAME-LLVM-NEXT: ]
+
+# INVALID-NAME-GNU:      warning: '[[FILE]]': unable to get the name of SHT_GNU_verneed section with index 1: a section [index 1] has an invalid sh_name (0xffffffff) offset which goes past the end of the section name string table
+# INVALID-NAME-GNU-NEXT: Version needs section '<?>' contains 1 entries:
+# INVALID-NAME-GNU-NEXT:  Addr: 0000000000000000  Offset: 0x000040  Link: 2 (.dynstr)
+# INVALID-NAME-GNU-NEXT:   0x0000: Version: 1  File: foo  Cnt: 1
+# INVALID-NAME-GNU-NEXT:   0x0010:   Name: foo  Flags: none  Version: 0
+
+## Check that llvm-readelf reports a warning when we are unable to read the name of
+## the section linked with the SHT_GNU_verneed section (usually ".dynstr").
+
+# RUN: yaml2obj --docnum=6 %s -DDYNSTRNAME=0xFFFFFFFF -o %t.invalid.name2
+# RUN: llvm-readobj -V %t.invalid.name2 2>&1 | \
+# RUN:   FileCheck %s -DFILE=%t.invalid.name2 --check-prefix=INVALID-NAME-LLVM --implicit-check-not=warning:
+# RUN: llvm-readelf -V %t.invalid.name2 2>&1 | \
+# RUN:   FileCheck %s -DFILE=%t.invalid.name2 --check-prefix=INVALID-NAME2-GNU --implicit-check-not=warning:
+
+# INVALID-NAME2-GNU:      Version needs section '.gnu.version_r' contains 1 entries:
+# INVALID-NAME2-GNU-NEXT: warning: '[[FILE]]': unable to get the name of SHT_STRTAB section with index 2: a section [index 2] has an invalid sh_name (0xffffffff) offset which goes past the end of the section name string table
+# INVALID-NAME2-GNU-NEXT:  Addr: 0000000000000000  Offset: 0x000040  Link: 2 (<?>)
+# INVALID-NAME2-GNU-NEXT:   0x0000: Version: 1  File: foo  Cnt: 1
+# INVALID-NAME2-GNU-NEXT:   0x0010:   Name: foo  Flags: none  Version: 0
+
 ## Check that we report a warning when we can't read the content of the SHT_GNU_verneed section.
 
 # RUN: yaml2obj --docnum=7 %s -o %t7

diff  --git a/llvm/test/tools/llvm-readobj/ELF/versym-invalid.test b/llvm/test/tools/llvm-readobj/ELF/versym-invalid.test
index 4064ce775dcd..9b665b949351 100644
--- a/llvm/test/tools/llvm-readobj/ELF/versym-invalid.test
+++ b/llvm/test/tools/llvm-readobj/ELF/versym-invalid.test
@@ -74,12 +74,12 @@ DynamicSymbols: []
 
 ## Check we report a warning when a SHT_GNU_versym section is not correctly aligned in memory.
 
-# RUN: yaml2obj --docnum=3 %s -o %t4
+# RUN: yaml2obj --docnum=3 %s -DSHOFFSET=0xffff -o %t4
 # RUN: llvm-readelf -V %t4 2>&1 | FileCheck -DFILE=%t4 %s --check-prefix=MISALIGNED-GNU
 # RUN: llvm-readobj -V %t4 2>&1 | FileCheck -DFILE=%t4 %s --check-prefix=MISALIGNED-LLVM
 
-# MISALIGNED-GNU:      Version symbols section '.gnu.version' contains 0 entries:
-# MISALIGNED-GNU-NEXT:  Addr: 0000000000000000  Offset: 0x00ffff  Link: 0 ()
+# MISALIGNED-GNU:      Version symbols section '.gnu.version' contains 1 entries:
+# MISALIGNED-GNU-NEXT:  Addr: 0000000000000000  Offset: 0x00ffff  Link: 2 (.dynsym)
 # MISALIGNED-GNU-NEXT:  warning: '[[FILE]]': the SHT_GNU_versym section with index 1 is misaligned
 
 # MISALIGNED-LLVM:      VersionSymbols [
@@ -92,10 +92,50 @@ FileHeader:
   Data:  ELFDATA2LSB
   Type:  ET_EXEC
 Sections:
-  - Name:    .gnu.version
-    Type:    SHT_GNU_versym
-    Entries: [ ]
-    ShOffset: 0xffff
+  - Name:     .gnu.version
+    Type:     SHT_GNU_versym
+    Entries:  [ 0 ]
+    Link:     .dynsym
+    ShOffset: [[SHOFFSET=<none>]]
+    ShName:   [[SHNAME=<none>]]
+  - Name:   .dynsym
+    Type:   SHT_DYNSYM
+    ShName: [[DYNSYMNAME=<none>]]
+DynamicSymbols: []
+
+## Check that llvm-readelf reports a warning when the name of the SHT_GNU_versym section can't be read.
+
+# RUN: yaml2obj %s --docnum=3 -DSHNAME=0xFF -o %t.invalid.name
+# RUN: llvm-readobj -V %t.invalid.name 2>&1 | \
+# RUN:   FileCheck %s --check-prefix=INVALID-NAME-LLVM -DFILE=%t.invalid.name --implicit-check-not=warning:
+# RUN: llvm-readelf -V %t.invalid.name 2>&1 | \
+# RUN:   FileCheck %s --check-prefix=INVALID-NAME-GNU -DFILE=%t.invalid.name --implicit-check-not=warning:
+
+# INVALID-NAME-LLVM:      VersionSymbols [
+# INVALID-NAME-LLVM-NEXT:   Symbol {
+# INVALID-NAME-LLVM-NEXT:     Version: 0
+# INVALID-NAME-LLVM-NEXT:     Name:
+# INVALID-NAME-LLVM-NEXT:   }
+# INVALID-NAME-LLVM-NEXT: ]
+
+# INVALID-NAME-GNU:      warning: '[[FILE]]': unable to get the name of SHT_GNU_versym section with index 1: a section [index 1] has an invalid sh_name (0xff) offset which goes past the end of the section name string table
+# INVALID-NAME-GNU-NEXT: Version symbols section '<?>' contains 1 entries:
+# INVALID-NAME-GNU-NEXT:  Addr: 0000000000000000  Offset: 0x000040  Link: 2 (.dynsym)
+# INVALID-NAME-GNU-NEXT:   000:   0 (*local*)
+
+## Check that llvm-readelf reports a warning when we are unable to read the name of
+## the section linked with the SHT_GNU_verneed section (usually ".dynsym").
+
+# RUN: yaml2obj %s --docnum=3 -DDYNSYMNAME=0xFF -o %t.invalid.name2
+# RUN: llvm-readobj -V %t.invalid.name2 2>&1 | \
+# RUN:   FileCheck %s --check-prefix=INVALID-NAME-LLVM -DFILE=%t.invalid.name2 --implicit-check-not=warning:
+# RUN: llvm-readelf -V %t.invalid.name2 2>&1 | \
+# RUN:   FileCheck %s --check-prefix=INVALID-NAME2-GNU -DFILE=%t.invalid.name2 --implicit-check-not=warning:
+
+# INVALID-NAME2-GNU:      Version symbols section '.gnu.version' contains 1 entries:
+# INVALID-NAME2-GNU-NEXT: warning: '[[FILE]]': unable to get the name of SHT_DYNSYM section with index 2: a section [index 2] has an invalid sh_name (0xff) offset which goes past the end of the section name string table
+# INVALID-NAME2-GNU-NEXT:  Addr: 0000000000000000  Offset: 0x000040  Link: 2 (<?>)
+# INVALID-NAME2-GNU-NEXT:   000:   0 (*local*)
 
 ## Check we report a warning when a SHT_GNU_versym section has an invalid entry size.
 

diff  --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index cdfbd1f20b2b..d1a5aa7e0e5d 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -952,7 +952,7 @@ template <typename ELFT> class GNUStyle : public DumpStyle<ELFT> {
   std::string getSymbolSectionNdx(const Elf_Sym &Symbol, unsigned SymIndex);
   void printProgramHeaders();
   void printSectionMapping();
-  void printGNUVersionSectionProlog(const typename ELFT::Shdr *Sec,
+  void printGNUVersionSectionProlog(const typename ELFT::Shdr &Sec,
                                     const Twine &Label, unsigned EntriesNum);
 };
 
@@ -4718,26 +4718,25 @@ template <class ELFT> void DumpStyle<ELFT>::printDynamicRelocationsHelper() {
 
 template <class ELFT>
 void GNUStyle<ELFT>::printGNUVersionSectionProlog(
-    const typename ELFT::Shdr *Sec, const Twine &Label, unsigned EntriesNum) {
-  StringRef SecName =
-      unwrapOrError(this->FileName, this->Obj.getSectionName(*Sec));
+    const typename ELFT::Shdr &Sec, const Twine &Label, unsigned EntriesNum) {
+  // Don't inline the SecName, because it might report a warning to stderr and
+  // corrupt the output.
+  StringRef SecName = this->getPrintableSectionName(Sec);
   OS << Label << " section '" << SecName << "' "
      << "contains " << EntriesNum << " entries:\n";
 
-  StringRef SymTabName = "<corrupt>";
-  Expected<const typename ELFT::Shdr *> SymTabOrErr =
-      this->Obj.getSection(Sec->sh_link);
-  if (SymTabOrErr)
-    SymTabName =
-        unwrapOrError(this->FileName, this->Obj.getSectionName(**SymTabOrErr));
+  StringRef LinkedSecName = "<corrupt>";
+  if (Expected<const typename ELFT::Shdr *> LinkedSecOrErr =
+          this->Obj.getSection(Sec.sh_link))
+    LinkedSecName = this->getPrintableSectionName(**LinkedSecOrErr);
   else
-    this->reportUniqueWarning(createError("invalid section linked to " +
-                                          describe(this->Obj, *Sec) + ": " +
-                                          toString(SymTabOrErr.takeError())));
+    this->reportUniqueWarning(
+        createError("invalid section linked to " + describe(this->Obj, Sec) +
+                    ": " + toString(LinkedSecOrErr.takeError())));
 
-  OS << " Addr: " << format_hex_no_prefix(Sec->sh_addr, 16)
-     << "  Offset: " << format_hex(Sec->sh_offset, 8)
-     << "  Link: " << Sec->sh_link << " (" << SymTabName << ")\n";
+  OS << " Addr: " << format_hex_no_prefix(Sec.sh_addr, 16)
+     << "  Offset: " << format_hex(Sec.sh_offset, 8)
+     << "  Link: " << Sec.sh_link << " (" << LinkedSecName << ")\n";
 }
 
 template <class ELFT>
@@ -4745,7 +4744,7 @@ void GNUStyle<ELFT>::printVersionSymbolSection(const Elf_Shdr *Sec) {
   if (!Sec)
     return;
 
-  printGNUVersionSectionProlog(Sec, "Version symbols",
+  printGNUVersionSectionProlog(*Sec, "Version symbols",
                                Sec->sh_size / sizeof(Elf_Versym));
   Expected<ArrayRef<Elf_Versym>> VerTableOrErr =
       this->dumper().getVersionTable(*Sec, /*SymTab=*/nullptr,
@@ -4818,7 +4817,7 @@ void GNUStyle<ELFT>::printVersionDefinitionSection(const Elf_Shdr *Sec) {
   if (!Sec)
     return;
 
-  printGNUVersionSectionProlog(Sec, "Version definition", Sec->sh_info);
+  printGNUVersionSectionProlog(*Sec, "Version definition", Sec->sh_info);
 
   Expected<std::vector<VerDef>> V = this->dumper().getVersionDefinitions(*Sec);
   if (!V) {
@@ -4846,7 +4845,7 @@ void GNUStyle<ELFT>::printVersionDependencySection(const Elf_Shdr *Sec) {
     return;
 
   unsigned VerneedNum = Sec->sh_info;
-  printGNUVersionSectionProlog(Sec, "Version needs", VerneedNum);
+  printGNUVersionSectionProlog(*Sec, "Version needs", VerneedNum);
 
   Expected<std::vector<VerNeed>> V =
       this->dumper().getVersionDependencies(*Sec);


        


More information about the llvm-commits mailing list