[llvm] ef85f47 - [llvm-readobj] Change errors to warnings for symbol section name dumping

James Henderson via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 4 04:04:55 PST 2019


Author: James Henderson
Date: 2019-11-04T12:04:04Z
New Revision: ef85f47595a905475d3e7b8d1441ed69cb226d9c

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

LOG: [llvm-readobj] Change errors to warnings for symbol section name dumping

Also only print each such warning once.

LLVM-style output will now print "<?>" for sections it cannot identify,
e.g. because the section index is invalid. GNU output continues to print
the raw index. In both cases where the st_shndx value is SHN_XINDEX and
the index cannot be looked up in the SHT_SYMTAB_SHNDX section (e.g.
because it is missing), the symbol is printed like other symbols with
st_shndx >= SHN_LORESERVE.

Reviewed by: grimar, MaskRay

Differential Revision: https://reviews.llvm.org/D69671

Added: 
    llvm/test/tools/llvm-readobj/elf-section-symbols.test

Modified: 
    llvm/test/Object/invalid.test
    llvm/test/tools/llvm-readobj/elf-symbol-shndx.test
    llvm/test/tools/yaml2obj/dynamic-symbols.yaml
    llvm/test/tools/yaml2obj/elf-sht-symtab-shndx.yaml
    llvm/tools/llvm-readobj/ELFDumper.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/test/Object/invalid.test b/llvm/test/Object/invalid.test
index 2c95eea74f24..ab498f237c9f 100644
--- a/llvm/test/Object/invalid.test
+++ b/llvm/test/Object/invalid.test
@@ -235,13 +235,14 @@ Symbols: []
 
 # INVALID-PH-ENTSIZE: error: '[[FILE]]': invalid e_phentsize: 12336
 
-## Check that llvm-readobj reports an error when we have no SHT_SYMTAB_SHNDX section,
+## Check that llvm-readobj reports a warning when we have no SHT_SYMTAB_SHNDX section,
 ## but have a symbol referencing it.
 
-# RUN: not llvm-readobj --symbols %p/Inputs/invalid-ext-symtab-index.elf-x86-64 2>&1 | \
+# RUN: llvm-readobj --symbols %p/Inputs/invalid-ext-symtab-index.elf-x86-64 2>&1 | \
 # RUN:   FileCheck -DFILE=%p/Inputs/invalid-ext-symtab-index.elf-x86-64 --check-prefix=INVALID-EXT-SYMTAB-INDEX %s
 
-# INVALID-EXT-SYMTAB-INDEX: error: '[[FILE]]': extended symbol index (0) is past the end of the SHT_SYMTAB_SHNDX section of size 0
+# INVALID-EXT-SYMTAB-INDEX: warning: '[[FILE]]': extended symbol index (0) is past the end of the SHT_SYMTAB_SHNDX section of size 0
+# INVALID-EXT-SYMTAB-INDEX: Section: Reserved (0xFFFF)
 
 ## Check that llvm-readobj reports an error if a relocation section
 ## has a broken sh_offset (past the end of the file).

diff  --git a/llvm/test/tools/llvm-readobj/elf-section-symbols.test b/llvm/test/tools/llvm-readobj/elf-section-symbols.test
new file mode 100644
index 000000000000..b6357766fc29
--- /dev/null
+++ b/llvm/test/tools/llvm-readobj/elf-section-symbols.test
@@ -0,0 +1,85 @@
+## ELF section symbols use the section names when printing. This test verifies
+## this and also that appropriate things are printed if the section is somehow
+## invalid.
+
+# RUN: yaml2obj %s -o %t1
+# RUN: llvm-readobj %t1 --symbols 2> %t.llvm.err1 | FileCheck %s --check-prefix=LLVM1
+# RUN: FileCheck %s --input-file %t.llvm.err1 --check-prefix=WARN1 --implicit-check-not=warning
+# RUN: llvm-readelf %t1 --symbols 2> %t.gnu.err1 | FileCheck %s --check-prefix=GNU1
+# RUN: FileCheck %s --input-file %t.gnu.err1 --check-prefix=WARN1 --implicit-check-not=warning
+
+# LLVM1: Name: (0)
+# LLVM1: Name: .foo (0)
+# LLVM1: Name: <section 67> (0)
+# LLVM1: Name: .bar (0)
+# LLVM1: Name: <section 66> (0)
+
+# GNU1:      Symbol table '.symtab' contains 5 entries:
+# GNU1-NEXT:    Num: {{.*}} Type    {{.*}} Ndx Name
+# GNU1-NEXT:      0: {{.*}} NOTYPE  {{.*}} UND {{$}}
+# GNU1-NEXT:      1: {{.*}} SECTION {{.*}}   1 .foo
+# GNU1-NEXT:      2: {{.*}} SECTION {{.*}}  67 <section 67>
+# GNU1-NEXT:      3: {{.*}} SECTION {{.*}}   2 .bar
+# GNU1-NEXT:      4: {{.*}} SECTION {{.*}}  66 <section 66>
+
+# WARN1: warning: '{{.*}}.tmp1': invalid section index: 67
+# WARN1: warning: '{{.*}}.tmp1': invalid section index: 66
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS32
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_386
+Sections:
+  - Name: .foo
+    Type: SHT_PROGBITS
+  - Name: .bar
+    Type: SHT_PROGBITS
+  - Name: .symtab_shndx
+    Type: SHT_SYMTAB_SHNDX
+    Link: .symtab
+    Entries: [ 0, 0, 0, 2, 0x42 ]
+Symbols:
+  - Name: ""
+    Section: .foo
+    Type: STT_SECTION
+  - Name: ""
+    Index: 0x43
+    Type: STT_SECTION
+  # Section symbol via SHT_SYMTAB_SHNDX.
+  - Name: ""
+    Index: SHN_XINDEX
+    Type: STT_SECTION
+  # Section symbol via SHT_SYMTAB_SHNDX with invalid index.
+  - Name: ""
+    Index: SHN_XINDEX
+    Type: STT_SECTION
+
+# RUN: yaml2obj %s --docnum=2 -o %t2
+# RUN: llvm-readobj %t2 --symbols 2> %t.llvm.err2 | FileCheck %s --check-prefix=LLVM2
+# RUN: FileCheck %s --input-file %t.llvm.err2 --check-prefix=WARN2 --implicit-check-not=warning
+# RUN: llvm-readelf %t2 --symbols 2> %t.gnu.err2 | FileCheck %s --check-prefix=GNU2
+# RUN: FileCheck %s --input-file %t.gnu.err2 --check-prefix=WARN2 --implicit-check-not=warning
+
+# LLVM2: Name: (0)
+# LLVM2: Name: <?> (0)
+
+# GNU2:      Symbol table '.symtab' contains 2 entries:
+# GNU2-NEXT:    Num: {{.*}} Type    {{.*}} Ndx Name
+# GNU2-NEXT:      0: {{.*}} NOTYPE  {{.*}} UND {{$}}
+# GNU2-NEXT:      1: {{.*}} SECTION {{.*}} RSV[0xffff] <?>
+
+# WARN2: warning: '{{.*}}.tmp2': extended symbol index (1) is past the end of the SHT_SYMTAB_SHNDX section of size 0
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS32
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_386
+Symbols:
+  # Section symbol via SHT_SYMTAB_SHNDX when SHT_SYMTAB_SHNDX is missing.
+  - Name: ""
+    Index: SHN_XINDEX
+    Type: STT_SECTION

diff  --git a/llvm/test/tools/llvm-readobj/elf-symbol-shndx.test b/llvm/test/tools/llvm-readobj/elf-symbol-shndx.test
index da3d1fa54cdf..ab01da9c842f 100644
--- a/llvm/test/tools/llvm-readobj/elf-symbol-shndx.test
+++ b/llvm/test/tools/llvm-readobj/elf-symbol-shndx.test
@@ -1,17 +1,12 @@
-# Show that llvm-readobj prints symbol shndxes correctly, for valid indexes,
-# invalid indexes (i.e. section indexes that don't correspond to a real
-# section), reserved values and processor/os-specific index values, for both GNU
-# and LLVM styles.
+## Show that llvm-readobj prints symbol shndxes correctly, for valid indexes,
+## invalid indexes (i.e. section indexes that don't correspond to a real
+## section), reserved values and processor/os-specific index values, for both GNU
+## and LLVM styles.
 
 # RUN: yaml2obj --docnum=1 %s > %t1
 # RUN: llvm-readobj --symbols %t1 | FileCheck %s --check-prefix=LLVM1
 # RUN: llvm-readelf --symbols %t1 | FileCheck %s --check-prefix=GNU1
 
-# llvm-readobj doesn't accept shndx values that are not valid section indexes
-# for LLVM style, so only test GNU output in this case.
-# RUN: yaml2obj --docnum=2 %s > %t2
-# RUN: llvm-readelf --symbols %t2 | FileCheck %s --check-prefix=GNU2
-
 # LLVM1: Name:    undef
 # LLVM1: Section:
 # LLVM1-SAME:     Undefined (0x0)
@@ -49,11 +44,6 @@
 # GNU1-NEXT:     7: {{.*}} RSV[0xfffe] reserved
 # GNU1-NEXT:     8: {{.*}}   1 xindex
 
-# GNU2:      Symbol table '.symtab' contains 2 entries:
-# GNU2-NEXT:   Num: {{.*}} Ndx Name
-# GNU2-NEXT:     0: {{.*}} UND
-# GNU2-NEXT:     1: {{.*}}  66 bad
-
 --- !ELF
 FileHeader:
   Class:   ELFCLASS32
@@ -92,13 +82,106 @@ Symbols:
     Index:   SHN_XINDEX
     Binding: STB_GLOBAL
 
+## In this case, the index does not correspond to a real section. Check that GNU
+## style just prints the section index as normal and LLVM style prints a warning
+## (but only once for each warning).
+# RUN: yaml2obj --docnum=2 %s > %t2
+# RUN: llvm-readobj --symbols %t2 2> %t2.llvm.err | FileCheck %s --check-prefix=LLVM2
+# RUN: FileCheck %s --input-file=%t2.llvm.err --check-prefix=BAD-SHNDX --implicit-check-not=warning
+# RUN: llvm-readelf --symbols %t2 2> %t2.gnu.err | FileCheck %s --check-prefix=GNU2
+# RUN: FileCheck %s --input-file=%t2.gnu.err --allow-empty --implicit-check-not={{.}}
+
+# LLVM2: Name: bad
+# LLVM2: Section:
+# LLVM2-SAME:     <?> (0x42)
+# LLVM2: Name: bad2
+# LLVM2: Section:
+# LLVM2-SAME:     <?> (0x42)
+# LLVM2: Name: bad3
+# LLVM2: Section:
+# LLVM2-SAME:     <?> (0x43)
+# LLVM2: Name: invalid_shndx
+# LLVM2: Section:
+# LLVM2-SAME:     <?> (0x9)
+# LLVM2: Name: invalid_shndx2
+# LLVM2: Section:
+# LLVM2-SAME:     <?> (0x9)
+# LLVM2: Name: invalid_shndx3
+# LLVM2: Section:
+# LLVM2-SAME:     <?> (0xA)
+
+# GNU2:      Symbol table '.symtab' contains 7 entries:
+# GNU2-NEXT:   Num: {{.*}} Ndx Name
+# GNU2-NEXT:     0: {{.*}} UND
+# GNU2-NEXT:     1: {{.*}}  66 bad
+# GNU2-NEXT:     2: {{.*}}  66 bad2
+# GNU2-NEXT:     3: {{.*}}  67 bad3
+# GNU2-NEXT:     4: {{.*}}   9 invalid_shndx
+# GNU2-NEXT:     5: {{.*}}   9 invalid_shndx2
+# GNU2-NEXT:     6: {{.*}}  10 invalid_shndx3
+
+# BAD-SHNDX: warning: '{{.*}}tmp2': invalid section index: 66
+# BAD-SHNDX: warning: '{{.*}}tmp2': invalid section index: 67
+# BAD-SHNDX: warning: '{{.*}}tmp2': invalid section index: 9
+# BAD-SHNDX: warning: '{{.*}}tmp2': invalid section index: 10
+
 --- !ELF
 FileHeader:
   Class:   ELFCLASS32
   Data:    ELFDATA2LSB
   Type:    ET_REL
   Machine: EM_386
+Sections:
+  - Name: .symtab_shndx
+    Type: SHT_SYMTAB_SHNDX
+    Link: .symtab
+    Entries: [ 0, 0, 0, 0, 9, 9, 10 ]
 Symbols:
   - Name:    bad
     Index:   0x42
-    Binding: STB_GLOBAL
+  - Name:    bad2
+    Index:   0x42
+  - Name:    bad3
+    Index:   0x43
+  - Name:    invalid_shndx
+    Index:   SHN_XINDEX
+  - Name:    invalid_shndx2
+    Index:   SHN_XINDEX
+  - Name:    invalid_shndx3
+    Index:   SHN_XINDEX
+
+## In this case, the symtab shndx section is missing, so symbols with section
+## indexes of SHN_XINDEX print as Reserved symbols.
+# RUN: yaml2obj --docnum=3 %s > %t3
+# RUN: llvm-readobj --symbols %t3 2> %t3.llvm.err | FileCheck %s --check-prefix=LLVM3
+# RUN: FileCheck %s --input-file=%t3.llvm.err --check-prefix=NO-SYMTAB-SHNDX --implicit-check-not=warning
+# RUN: llvm-readelf --symbols %t3 2> %t3.gnu.err | FileCheck %s --check-prefix=GNU3
+# RUN: FileCheck %s --input-file=%t3.gnu.err --check-prefix=NO-SYMTAB-SHNDX --implicit-check-not=warning
+
+# LLVM3: Name: no_shndx
+# LLVM3: Section:
+# LLVM3-SAME:     Reserved (0xFFFF)
+# LLVM3: Name: no_shndx2
+# LLVM3: Section:
+# LLVM3-SAME:     Reserved (0xFFFF)
+
+# GNU3:      Symbol table '.symtab' contains 3 entries:
+# GNU3-NEXT:   Num: {{.*}} Ndx Name
+# GNU3-NEXT:     0: {{.*}} UND
+# GNU3-NEXT:     1: {{.*}} RSV[0xffff] no_shndx
+# GNU3-NEXT:     2: {{.*}} RSV[0xffff] no_shndx2
+
+# NO-SYMTAB-SHNDX: warning: '{{.*}}tmp3': extended symbol index (1) is past the end of the SHT_SYMTAB_SHNDX section of size 0
+# NO-SYMTAB-SHNDX: warning: '{{.*}}tmp3': extended symbol index (2) is past the end of the SHT_SYMTAB_SHNDX section of size 0
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS32
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_386
+Symbols:
+  - Name:  no_shndx
+    Index: SHN_XINDEX
+  - Name:  no_shndx2
+    Index: SHN_XINDEX

diff  --git a/llvm/test/tools/yaml2obj/dynamic-symbols.yaml b/llvm/test/tools/yaml2obj/dynamic-symbols.yaml
index 7eb58fa61892..c088a1199be4 100644
--- a/llvm/test/tools/yaml2obj/dynamic-symbols.yaml
+++ b/llvm/test/tools/yaml2obj/dynamic-symbols.yaml
@@ -44,7 +44,7 @@ DynamicSymbols:
 ## Check we can use numeric values to refer to sections.
 
 # RUN: yaml2obj --docnum=2 %s -o %t2
-# RUN: not llvm-readobj --dyn-symbols %t2 2>&1 | FileCheck -DFILE=%t2 %s --check-prefix=NUM
+# RUN: llvm-readobj --dyn-symbols %t2 2>&1 | FileCheck -DFILE=%t2 %s --check-prefix=NUM
 
 # NUM:      Name: foo
 # NUM:      Section:
@@ -54,7 +54,10 @@ DynamicSymbols:
 # NUM:      Section: 
 # NUM-SAME: .strtab (0x2)
 
-# NUM: error: '[[FILE]]': invalid section index: 255
+# NUM:      Name: zed
+# NUM: warning: '[[FILE]]': invalid section index: 255
+# NUM:      Section: 
+# NUM-SAME: <?> (0xFF)
 
 --- !ELF
 FileHeader:

diff  --git a/llvm/test/tools/yaml2obj/elf-sht-symtab-shndx.yaml b/llvm/test/tools/yaml2obj/elf-sht-symtab-shndx.yaml
index 612087a305c8..7175f465a668 100644
--- a/llvm/test/tools/yaml2obj/elf-sht-symtab-shndx.yaml
+++ b/llvm/test/tools/yaml2obj/elf-sht-symtab-shndx.yaml
@@ -3,9 +3,9 @@
 ## but no SHT_SYMTAB_SHNDX section is defined.
 
 # RUN: yaml2obj --docnum=1 %s -o %t1
-# RUN: not llvm-readobj --symbols 2>&1 %t1 | FileCheck -DFILE=%t1 %s --check-prefix=CASE1
+# RUN: llvm-readobj --symbols 2>&1 %t1 | FileCheck -DFILE=%t1 %s --check-prefix=CASE1
 
-# CASE1: error: '[[FILE]]': extended symbol index (1) is past the end of the SHT_SYMTAB_SHNDX section of size 0
+# CASE1: warning: '[[FILE]]': extended symbol index (1) is past the end of the SHT_SYMTAB_SHNDX section of size 0
 
 --- !ELF
 FileHeader:
@@ -71,9 +71,9 @@ Symbols:
 ## which is larger than the total number of sections in the file).
 
 # RUN: yaml2obj --docnum=3 %s -o %t3
-# RUN: not llvm-readobj --symbols 2>&1 %t3 | FileCheck %s -DFILE=%t3 --check-prefix=CASE3
+# RUN: llvm-readobj --symbols 2>&1 %t3 | FileCheck %s -DFILE=%t3 --check-prefix=CASE3
 
-# CASE3: error: '[[FILE]]': invalid section index: 255
+# CASE3: warning: '[[FILE]]': invalid section index: 255
 
 --- !ELF
 FileHeader:

diff  --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index e48744b2f76d..f83331dbb965 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -433,6 +433,8 @@ template <typename ELFT> class DumpStyle {
   virtual void printMipsABIFlags(const ELFObjectFile<ELFT> *Obj) = 0;
   const ELFDumper<ELFT> *dumper() const { return Dumper; }
 
+  void reportUniqueWarning(Error Err) const;
+
 protected:
   std::function<Error(const Twine &Msg)> WarningHandler;
   StringRef FileName;
@@ -556,6 +558,14 @@ template <typename ELFT> class GNUStyle : public DumpStyle<ELFT> {
   void printSectionMapping(const ELFO *Obj);
 };
 
+template <class ELFT>
+void DumpStyle<ELFT>::reportUniqueWarning(Error Err) const {
+  handleAllErrors(std::move(Err), [&](const ErrorInfoBase &EI) {
+    cantFail(WarningHandler(EI.message()),
+             "WarningHandler should always return ErrorSuccess");
+  });
+}
+
 template <typename ELFT> class LLVMStyle : public DumpStyle<ELFT> {
 public:
   TYPEDEF_ELF_TYPES(ELFT)
@@ -824,10 +834,18 @@ std::string ELFDumper<ELFT>::getFullSymbolName(const Elf_Sym *Symbol,
   if (SymbolName.empty() && Symbol->getType() == ELF::STT_SECTION) {
     Elf_Sym_Range Syms = unwrapOrError(
         ObjF->getFileName(), ObjF->getELFFile()->symbols(DotSymtabSec));
-    unsigned SectionIndex = unwrapOrError(
-        ObjF->getFileName(), getSymbolSectionIndex(Symbol, Syms.begin()));
-    return unwrapOrError(ObjF->getFileName(),
-                         getSymbolSectionName(Symbol, SectionIndex));
+    Expected<unsigned> SectionIndex =
+        getSymbolSectionIndex(Symbol, Syms.begin());
+    if (!SectionIndex) {
+      ELFDumperStyle->reportUniqueWarning(SectionIndex.takeError());
+      return "<?>";
+    }
+    Expected<StringRef> NameOrErr = getSymbolSectionName(Symbol, *SectionIndex);
+    if (!NameOrErr) {
+      ELFDumperStyle->reportUniqueWarning(NameOrErr.takeError());
+      return ("<section " + Twine(*SectionIndex) + ">").str();
+    }
+    return *NameOrErr;
   }
 
   if (!IsDynamic)
@@ -3298,12 +3316,18 @@ std::string GNUStyle<ELFT>::getSymbolSectionNdx(const ELFO *Obj,
     return "ABS";
   case ELF::SHN_COMMON:
     return "COM";
-  case ELF::SHN_XINDEX:
-    return to_string(format_decimal(
-        unwrapOrError(this->FileName,
-                      object::getExtendedSymbolTableIndex<ELFT>(
-                          Symbol, FirstSym, this->dumper()->getShndxTable())),
-        3));
+  case ELF::SHN_XINDEX: {
+    Expected<uint32_t> IndexOrErr = object::getExtendedSymbolTableIndex<ELFT>(
+        Symbol, FirstSym, this->dumper()->getShndxTable());
+    if (!IndexOrErr) {
+      assert(Symbol->st_shndx == SHN_XINDEX &&
+             "getSymbolSectionIndex should only fail due to an invalid "
+             "SHT_SYMTAB_SHNDX table/reference");
+      this->reportUniqueWarning(IndexOrErr.takeError());
+      return "RSV[0xffff]";
+    }
+    return to_string(format_decimal(*IndexOrErr, 3));
+  }
   default:
     // Find if:
     // Processor specific
@@ -5454,11 +5478,25 @@ void LLVMStyle<ELFT>::printSectionHeaders(const ELFO *Obj) {
 template <class ELFT>
 void LLVMStyle<ELFT>::printSymbolSection(const Elf_Sym *Symbol,
                                          const Elf_Sym *First) {
-  unsigned SectionIndex = unwrapOrError(
-      this->FileName, this->dumper()->getSymbolSectionIndex(Symbol, First));
-  StringRef SectionName = unwrapOrError(
-      this->FileName, this->dumper()->getSymbolSectionName(Symbol, SectionIndex));
-  W.printHex("Section", SectionName, SectionIndex);
+  Expected<unsigned> SectionIndex =
+      this->dumper()->getSymbolSectionIndex(Symbol, First);
+  if (!SectionIndex) {
+    assert(Symbol->st_shndx == SHN_XINDEX &&
+           "getSymbolSectionIndex should only fail due to an invalid "
+           "SHT_SYMTAB_SHNDX table/reference");
+    this->reportUniqueWarning(SectionIndex.takeError());
+    W.printHex("Section", "Reserved", SHN_XINDEX);
+    return;
+  }
+
+  Expected<StringRef> SectionName =
+      this->dumper()->getSymbolSectionName(Symbol, *SectionIndex);
+  if (!SectionName) {
+    this->reportUniqueWarning(SectionName.takeError());
+    W.printHex("Section", "<?>", *SectionIndex);
+  } else {
+    W.printHex("Section", *SectionName, *SectionIndex);
+  }
 }
 
 template <class ELFT>


        


More information about the llvm-commits mailing list