[llvm] 7f362f0 - [llvm-readelf] - Make GNU style dumping of invalid SHT_GNU_verdef be consistent with LLVM style.

Georgii Rymar via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 28 01:41:51 PST 2019


Author: Georgii Rymar
Date: 2019-11-28T12:41:29+03:00
New Revision: 7f362f04a7812111dec7eb11279a53566e09cdfb

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

LOG: [llvm-readelf] - Make GNU style dumping of invalid SHT_GNU_verdef be consistent with LLVM style.

When we dump SHT_GNU_verdef section that has sh_link that references a non-existent section,
llvm-readobj reports a warning and continues dump, but llvm-readelf fails with a error.

This patch fixes the issue and opens road for futher follow-ups for
improving the printGNUVersionSectionProlog().

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

Added: 
    

Modified: 
    llvm/test/tools/llvm-readobj/elf-verdef-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 493537464a00..3a4de3698385 100644
--- a/llvm/test/tools/llvm-readobj/elf-verdef-invalid.test
+++ b/llvm/test/tools/llvm-readobj/elf-verdef-invalid.test
@@ -3,14 +3,14 @@
 ## Check that we report a warning when sh_link references a non-existent section.
 
 # RUN: yaml2obj %s --docnum=1 -o %t1
-# RUN: llvm-readobj -V %t1 2>&1 | FileCheck %s --check-prefix=INVALID-LINK-LLVM -DFILE=%t1
-# RUN: not llvm-readelf -V %t1 2>&1 | FileCheck %s --check-prefix=INVALID-LINK-GNU -DFILE=%t1
+# RUN: llvm-readobj -V %t1 2>&1 | FileCheck %s --check-prefix=INVALID-LINK-LLVM --implicit-check-not="warning:" -DFILE=%t1
+# RUN: llvm-readelf -V %t1 2>&1 | FileCheck %s --check-prefix=INVALID-LINK-GNU --implicit-check-not="warning:" -DFILE=%t1
 
 # INVALID-LINK-LLVM: warning: '[[FILE]]': invalid section linked to SHT_GNU_verdef section with index 1: invalid section index: 255
 
-## TODO: llvm-readelf should also report a meaningful warning instead of an error.
-# INVALID-LINK-GNU: Version definition
-# INVALID-LINK-GNU: error: '[[FILE]]': invalid section index: 255
+# INVALID-LINK-GNU:      Version definition section '.gnu.version_d' contains 0 entries:
+# INVALID-LINK-GNU:      warning: '[[FILE]]': invalid section linked to SHT_GNU_verdef section with index 1: invalid section index: 255
+# INVALID-LINK-GNU-NEXT:  Addr: 0000000000000000  Offset: 0x000040  Link: 255 (<corrupt>)
 
 --- !ELF
 FileHeader:

diff  --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index b7bd35e7c95c..79d08d379a1a 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -672,6 +672,9 @@ template <typename ELFT> class GNUStyle : public DumpStyle<ELFT> {
   bool checkPTDynamic(const Elf_Phdr &Phdr, const Elf_Shdr &Sec);
   void printProgramHeaders(const ELFO *Obj);
   void printSectionMapping(const ELFO *Obj);
+  void printGNUVersionSectionProlog(const ELFFile<ELFT> *Obj,
+                                    const typename ELFT::Shdr *Sec,
+                                    const Twine &Label, unsigned EntriesNum);
 };
 
 template <class ELFT>
@@ -3921,18 +3924,26 @@ void GNUStyle<ELFT>::printDynamicRelocations(const ELFO *Obj) {
 }
 
 template <class ELFT>
-static void printGNUVersionSectionProlog(formatted_raw_ostream &OS,
-                                         const Twine &Name, unsigned EntriesNum,
-                                         const ELFFile<ELFT> *Obj,
-                                         const typename ELFT::Shdr *Sec,
-                                         StringRef FileName) {
-  StringRef SecName = unwrapOrError(FileName, Obj->getSectionName(Sec));
-  OS << Name << " section '" << SecName << "' "
+void GNUStyle<ELFT>::printGNUVersionSectionProlog(
+    const ELFFile<ELFT> *Obj, const typename ELFT::Shdr *Sec,
+    const Twine &Label, unsigned EntriesNum) {
+  StringRef SecName = unwrapOrError(this->FileName, Obj->getSectionName(Sec));
+  OS << Label << " section '" << SecName << "' "
      << "contains " << EntriesNum << " entries:\n";
 
-  const typename ELFT::Shdr *SymTab =
-      unwrapOrError(FileName, Obj->getSection(Sec->sh_link));
-  StringRef SymTabName = unwrapOrError(FileName, Obj->getSectionName(SymTab));
+  unsigned SecNdx = Sec - &cantFail(Obj->sections()).front();
+  StringRef SymTabName = "<corrupt>";
+
+  Expected<const typename ELFT::Shdr *> SymTabOrErr =
+      Obj->getSection(Sec->sh_link);
+  if (SymTabOrErr)
+    SymTabName =
+        unwrapOrError(this->FileName, Obj->getSectionName(*SymTabOrErr));
+  else
+    this->reportUniqueWarning(createError(
+        "invalid section linked to SHT_GNU_verdef section with index " +
+        Twine(SecNdx) + ": " + toString(SymTabOrErr.takeError())));
+
   OS << " Addr: " << format_hex_no_prefix(Sec->sh_addr, 16)
      << "  Offset: " << format_hex(Sec->sh_offset, 8)
      << "  Link: " << Sec->sh_link << " (" << SymTabName << ")\n";
@@ -3945,8 +3956,7 @@ void GNUStyle<ELFT>::printVersionSymbolSection(const ELFFile<ELFT> *Obj,
     return;
 
   unsigned Entries = Sec->sh_size / sizeof(Elf_Versym);
-  printGNUVersionSectionProlog(OS, "Version symbols", Entries, Obj, Sec,
-                               this->FileName);
+  printGNUVersionSectionProlog(Obj, Sec, "Version symbols", Entries);
 
   const uint8_t *VersymBuf =
       reinterpret_cast<const uint8_t *>(Obj->base() + Sec->sh_offset);
@@ -4017,8 +4027,7 @@ void GNUStyle<ELFT>::printVersionDefinitionSection(const ELFFile<ELFT> *Obj,
   if (!Sec)
     return;
 
-  printGNUVersionSectionProlog(OS, "Version definition", Sec->sh_info, Obj, Sec,
-                               this->FileName);
+  printGNUVersionSectionProlog(Obj, Sec, "Version definition", Sec->sh_info);
 
   Expected<std::vector<VerDef>> V = this->dumper()->getVersionDefinitions(Sec);
   if (!V) {
@@ -4047,8 +4056,7 @@ void GNUStyle<ELFT>::printVersionDependencySection(const ELFFile<ELFT> *Obj,
     return;
 
   unsigned VerneedNum = Sec->sh_info;
-  printGNUVersionSectionProlog(OS, "Version needs", VerneedNum, Obj, Sec,
-                               this->FileName);
+  printGNUVersionSectionProlog(Obj, Sec, "Version needs", VerneedNum);
 
   ArrayRef<uint8_t> SecData =
       unwrapOrError(this->FileName, Obj->getSectionContents(Sec));


        


More information about the llvm-commits mailing list