[llvm] r366203 - [Object/llvm-readelf/llvm-readobj] - Improve error reporting when e_shstrndx is broken.

George Rimar via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 16 04:07:30 PDT 2019


Author: grimar
Date: Tue Jul 16 04:07:30 2019
New Revision: 366203

URL: http://llvm.org/viewvc/llvm-project?rev=366203&view=rev
Log:
[Object/llvm-readelf/llvm-readobj] - Improve error reporting when e_shstrndx is broken.

When e_shstrndx is broken, it is impossible to get a section name.
In this patch I improved the error message we show and 
added tests for Object and for llvm-readelf/llvm-readobj

Message was changed in two places:
1) llvm-readelf/llvm-readobj previously used a code from Object/ELF.h,
now they have a modified version of it (it has less checks and allows
dumping broken things).
2) Code in Object/ELF.h is still used for generic cases.

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

Added:
    llvm/trunk/test/tools/llvm-readobj/elf-invalid-shstrndx.test
Modified:
    llvm/trunk/include/llvm/Object/ELF.h
    llvm/trunk/test/Object/invalid.test
    llvm/trunk/tools/llvm-readobj/ELFDumper.cpp
    llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp
    llvm/trunk/tools/llvm-readobj/llvm-readobj.h

Modified: llvm/trunk/include/llvm/Object/ELF.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/ELF.h?rev=366203&r1=366202&r2=366203&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/ELF.h (original)
+++ llvm/trunk/include/llvm/Object/ELF.h Tue Jul 16 04:07:30 2019
@@ -466,9 +466,10 @@ ELFFile<ELFT>::getSectionStringTable(Elf
 
   if (!Index) // no section string table.
     return "";
+  // TODO: Test a case when the sh_link of the section with index 0 is broken.
   if (Index >= Sections.size())
-    // TODO: this error is untested.
-    return createError("invalid section index");
+    return createError("section header string table index " + Twine(Index) +
+                       " does not exist");
   return getStringTable(&Sections[Index]);
 }
 

Modified: llvm/trunk/test/Object/invalid.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/invalid.test?rev=366203&r1=366202&r2=366203&view=diff
==============================================================================
--- llvm/trunk/test/Object/invalid.test (original)
+++ llvm/trunk/test/Object/invalid.test Tue Jul 16 04:07:30 2019
@@ -536,3 +536,19 @@ ProgramHeaders:
     FileSize: 0xffff0000
     Sections:
       - Section: .dynamic
+
+# RUN: yaml2obj --docnum=25 %s -o %t25
+# RUN: not obj2yaml 2>&1 %t25 | FileCheck %s -DFILE=%t25 --check-prefix=INVALID-SHSTRNDX
+
+# INVALID-SHSTRNDX: Error reading file: [[FILE]]: section header string table index 255 does not exist
+
+--- !ELF
+FileHeader:
+  Class:    ELFCLASS64
+  Data:     ELFDATA2LSB
+  Type:     ET_REL
+  Machine:  EM_X86_64
+  SHStrNdx: 0xFF
+Sections:
+  - Name: .foo
+    Type: SHT_PROGBITS

Added: llvm/trunk/test/tools/llvm-readobj/elf-invalid-shstrndx.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/elf-invalid-shstrndx.test?rev=366203&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-readobj/elf-invalid-shstrndx.test (added)
+++ llvm/trunk/test/tools/llvm-readobj/elf-invalid-shstrndx.test Tue Jul 16 04:07:30 2019
@@ -0,0 +1,26 @@
+# RUN: yaml2obj %s -o %t
+# RUN: not llvm-readelf --headers -S 2>&1 %t | FileCheck %s -DFILE=%t --check-prefix=GNU
+# RUN: not llvm-readobj --headers -S 2>&1 %t | FileCheck %s -DFILE=%t --check-prefix=LLVM
+
+# GNU:      ELF Header:
+# GNU:        Section header string table index: 255
+# GNU-NEXT:   There are 4 section headers, starting at offset 0x40:
+# GNU:      Section Headers:
+# GNU-NEXT:  [Nr] Name
+# GNU-EMPTY:
+# GNU-NEXT:  error: '[[FILE]]': section header string table index 255 does not exist
+
+# LLVM:      ElfHeader {
+# LLVM:        StringTableSectionIndex: 255
+# LLVM-NEXT: }
+# LLVM-NEXT: Sections [
+# LLVM-EMPTY:
+# LLVM-NEXT: error: '[[FILE]]': section header string table index 255 does not exist
+
+--- !ELF
+FileHeader:
+  Class:     ELFCLASS64
+  Data:      ELFDATA2LSB
+  Type:      ET_REL
+  Machine:   EM_X86_64
+  SHStrNdx:  0xFF

Modified: llvm/trunk/tools/llvm-readobj/ELFDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/ELFDumper.cpp?rev=366203&r1=366202&r2=366203&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/ELFDumper.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/ELFDumper.cpp Tue Jul 16 04:07:30 2019
@@ -183,6 +183,8 @@ public:
 
   void printELFLinkerOptions() override;
 
+  const object::ELFObjectFile<ELFT> *getElfObject() const { return ObjF; };
+
 private:
   std::unique_ptr<DumpStyle<ELFT>> ELFDumperStyle;
 
@@ -3009,15 +3011,19 @@ static std::string getSectionTypeString(
 
 template <class ELFT>
 static StringRef getSectionName(const typename ELFT::Shdr &Sec,
-                                const ELFFile<ELFT> &Obj,
+                                const ELFObjectFile<ELFT> &ElfObj,
                                 ArrayRef<typename ELFT::Shdr> Sections) {
+  const ELFFile<ELFT> &Obj = *ElfObj.getELFFile();
   uint32_t Index = Obj.getHeader()->e_shstrndx;
   if (Index == ELF::SHN_XINDEX)
     Index = Sections[0].sh_link;
   if (!Index) // no section string table.
     return "";
+  // TODO: Test a case when the sh_link of the section with index 0 is broken.
   if (Index >= Sections.size())
-    reportError("invalid section index");
+    reportError(ElfObj.getFileName(),
+                createError("section header string table index " +
+                            Twine(Index) + " does not exist"));
   StringRef Data = toStringRef(unwrapOrError(
       Obj.template getSectionContentsAsArray<uint8_t>(&Sections[Index])));
   return unwrapOrError(Obj.getSectionName(&Sec, Data));
@@ -3040,10 +3046,11 @@ void GNUStyle<ELFT>::printSectionHeaders
     printField(F);
   OS << "\n";
 
+  const ELFObjectFile<ELFT> *ElfObj = this->dumper()->getElfObject();
   size_t SectionIndex = 0;
   for (const Elf_Shdr &Sec : Sections) {
     Fields[0].Str = to_string(SectionIndex);
-    Fields[1].Str = getSectionName(Sec, *Obj, Sections);
+    Fields[1].Str = getSectionName(Sec, *ElfObj, Sections);
     Fields[2].Str =
         getSectionTypeString(Obj->getHeader()->e_machine, Sec.sh_type);
     Fields[3].Str =
@@ -4590,8 +4597,9 @@ void LLVMStyle<ELFT>::printSectionHeader
 
   int SectionIndex = -1;
   ArrayRef<Elf_Shdr> Sections = unwrapOrError(Obj->sections());
+  const ELFObjectFile<ELFT> *ElfObj = this->dumper()->getElfObject();
   for (const Elf_Shdr &Sec : Sections) {
-    StringRef Name = getSectionName(Sec, *Obj, Sections);
+    StringRef Name = getSectionName(Sec, *ElfObj, Sections);
     DictScope SectionD(W, "Section");
     W.printNumber("Index", ++SectionIndex);
     W.printNumber("Name", Name, Sec.sh_name);

Modified: llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp?rev=366203&r1=366202&r2=366203&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp Tue Jul 16 04:07:30 2019
@@ -371,11 +371,18 @@ namespace opts {
 namespace llvm {
 
 LLVM_ATTRIBUTE_NORETURN void reportError(Twine Msg) {
+  fouts().flush();
   errs() << "\n";
   WithColor::error(errs()) << Msg << "\n";
   exit(1);
 }
 
+void reportError(StringRef Input, Error Err) {
+  if (Input == "-")
+    Input = "<stdin>";
+  error(createFileError(Input, std::move(Err)));
+}
+
 void reportWarning(Twine Msg) {
   fouts().flush();
   errs() << "\n";
@@ -403,12 +410,6 @@ void error(std::error_code EC) {
 
 } // namespace llvm
 
-static void reportError(StringRef Input, Error Err) {
-  if (Input == "-")
-    Input = "<stdin>";
-  error(createFileError(Input, std::move(Err)));
-}
-
 static void reportError(StringRef Input, std::error_code EC) {
   reportError(Input, errorCodeToError(EC));
 }

Modified: llvm/trunk/tools/llvm-readobj/llvm-readobj.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/llvm-readobj.h?rev=366203&r1=366202&r2=366203&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/llvm-readobj.h (original)
+++ llvm/trunk/tools/llvm-readobj/llvm-readobj.h Tue Jul 16 04:07:30 2019
@@ -22,6 +22,7 @@ namespace llvm {
 
   // Various helper functions.
   LLVM_ATTRIBUTE_NORETURN void reportError(Twine Msg);
+  void reportError(StringRef Input, Error Err); 
   void reportWarning(Twine Msg);
   void warn(llvm::Error Err);
   void error(std::error_code EC);




More information about the llvm-commits mailing list