[llvm] r370330 - [llvm-readobj/llvm-readelf] - Report a proper warning when dumping a broken dynamic relocation.

George Rimar via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 29 03:55:57 PDT 2019


Author: grimar
Date: Thu Aug 29 03:55:57 2019
New Revision: 370330

URL: http://llvm.org/viewvc/llvm-project?rev=370330&view=rev
Log:
[llvm-readobj/llvm-readelf] - Report a proper warning when dumping a broken dynamic relocation.

When we have a dynamic relocation with a broken symbol's st_name,
tools report a useless error: "Invalid data was encountered while parsing the file".

After this change we report a warning + "<corrupt>" as a symbol name.

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

Added:
    llvm/trunk/test/tools/llvm-readobj/elf-broken-dynamic-reloc-name.test
Modified:
    llvm/trunk/include/llvm/Object/ELFTypes.h
    llvm/trunk/test/Object/invalid.test
    llvm/trunk/tools/llvm-readobj/ELFDumper.cpp

Modified: llvm/trunk/include/llvm/Object/ELFTypes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/ELFTypes.h?rev=370330&r1=370329&r2=370330&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/ELFTypes.h (original)
+++ llvm/trunk/include/llvm/Object/ELFTypes.h Thu Aug 29 03:55:57 2019
@@ -248,7 +248,11 @@ template <class ELFT>
 Expected<StringRef> Elf_Sym_Impl<ELFT>::getName(StringRef StrTab) const {
   uint32_t Offset = this->st_name;
   if (Offset >= StrTab.size())
-    return errorCodeToError(object_error::parse_failed);
+    return createStringError(object_error::parse_failed,
+                             "st_name (0x%" PRIx32
+                             ") is past the end of the string table"
+                             " of size 0x%zx",
+                             Offset, StrTab.size());
   return StringRef(StrTab.data() + Offset);
 }
 

Modified: llvm/trunk/test/Object/invalid.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/invalid.test?rev=370330&r1=370329&r2=370330&view=diff
==============================================================================
--- llvm/trunk/test/Object/invalid.test (original)
+++ llvm/trunk/test/Object/invalid.test Thu Aug 29 03:55:57 2019
@@ -390,7 +390,7 @@ Sections:
 # RUN: yaml2obj %s --docnum=19 -o %t19
 # RUN: not llvm-readobj --symbols %t19 2>&1 | FileCheck -DFILE=%t19 --check-prefix=INVALID-SYM-NAME %s
 
-# INVALID-SYM-NAME: error: '[[FILE]]': Invalid data was encountered while parsing the file
+# INVALID-SYM-NAME: error: '[[FILE]]': st_name (0x1) is past the end of the string table of size 0x1
 
 --- !ELF
 FileHeader:

Added: llvm/trunk/test/tools/llvm-readobj/elf-broken-dynamic-reloc-name.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/elf-broken-dynamic-reloc-name.test?rev=370330&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-readobj/elf-broken-dynamic-reloc-name.test (added)
+++ llvm/trunk/test/tools/llvm-readobj/elf-broken-dynamic-reloc-name.test Thu Aug 29 03:55:57 2019
@@ -0,0 +1,51 @@
+## Check that llvm-readobj/llvm-readelf reports an error when dumping relocations if a dynamic
+## symbol name offset is broken (goes past the end of the dynamic symbol string table).
+
+# RUN: yaml2obj %s -o %t
+# RUN: llvm-readobj --dyn-relocations %t 2>&1 | FileCheck %s -DFILE=%t --check-prefix=LLVM
+# RUN: llvm-readelf --dyn-relocations %t 2>&1 | FileCheck %s -DFILE=%t --check-prefix=GNU
+
+# LLVM:      Dynamic Relocations {
+# LLVM-EMPTY:
+# LLVM-NEXT: warning: '[[FILE]]': unable to get name of the dynamic symbol with index 1: st_name (0x1234) is past the end of the string table of size 0x1
+# LLVM-NEXT:   0x0 R_X86_64_NONE <corrupt> 0x0
+# LLVM-NEXT: }
+
+# GNU:      'RELA' relocation section at offset {{.+}} contains 24 bytes:
+# GNU-NEXT: Offset           Info             Type          Symbol's Value   Symbol's Name + Addend
+# GNU-EMPTY:
+# GNU-NEXT: warning: '[[FILE]]': unable to get name of the dynamic symbol with index 1: st_name (0x1234) is past the end of the string table of size 0x1
+# GNU-NEXT: 0000000000000000 0000000100000000 R_X86_64_NONE 0000000000000000 <corrupt> + 0
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_DYN
+  Machine: EM_X86_64
+Sections:
+  - Name:    .rela.dyn
+    Type:    SHT_RELA
+    Link:    .dynsym
+    Relocations:
+      - Offset: 0x0
+        Symbol: 1 ## Index of a dynamic symbol with a broken st_name.
+        Type:   R_X86_64_NONE
+  - Name: .dynamic
+    Type: SHT_DYNAMIC
+    Entries:
+      - Tag:   DT_RELA
+        Value: 0x0000000000000000
+      - Tag:   DT_RELASZ
+        Value: 0x0000000000000018
+      - Tag:   DT_RELAENT
+        Value: 0x0000000000000018
+      - Tag:   DT_NULL
+        Value: 0x0000000000000000
+DynamicSymbols:
+  - NameIndex: 0x1234
+ProgramHeaders:
+  - Type:  PT_LOAD
+    Sections:
+      - Section: .rela.dyn
+      - Section: .dynamic

Modified: llvm/trunk/tools/llvm-readobj/ELFDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/ELFDumper.cpp?rev=370330&r1=370329&r2=370330&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/ELFDumper.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/ELFDumper.cpp Thu Aug 29 03:55:57 2019
@@ -3525,14 +3525,40 @@ void GNUStyle<ELFT>::printSectionMapping
   }
 }
 
+namespace {
+template <class ELFT> struct RelSymbol {
+  const typename ELFT::Sym *Sym;
+  std::string Name;
+};
+
+template <class ELFT>
+RelSymbol<ELFT> getSymbolForReloc(const ELFFile<ELFT> *Obj, StringRef FileName,
+                                  const ELFDumper<ELFT> *Dumper,
+                                  const typename ELFT::Rela &Reloc) {
+  uint32_t SymIndex = Reloc.getSymbol(Obj->isMips64EL());
+  const typename ELFT::Sym *Sym = Dumper->dynamic_symbols().begin() + SymIndex;
+  Expected<StringRef> ErrOrName = Sym->getName(Dumper->getDynamicStringTable());
+
+  std::string Name;
+  if (ErrOrName) {
+    Name = maybeDemangle(*ErrOrName);
+  } else {
+    reportWarning(
+        createError("unable to get name of the dynamic symbol with index " +
+                    Twine(SymIndex) + ": " + toString(ErrOrName.takeError())),
+        FileName);
+    Name = "<corrupt>";
+  }
+
+  return {Sym, std::move(Name)};
+}
+} // namespace
+
 template <class ELFT>
 void GNUStyle<ELFT>::printDynamicRelocation(const ELFO *Obj, Elf_Rela R,
                                             bool IsRela) {
-  uint32_t SymIndex = R.getSymbol(Obj->isMips64EL());
-  const Elf_Sym *Sym = this->dumper()->dynamic_symbols().begin() + SymIndex;
-  std::string SymbolName = maybeDemangle(unwrapOrError(
-      this->FileName, Sym->getName(this->dumper()->getDynamicStringTable())));
-  printRelocation(Obj, Sym, SymbolName, R, IsRela);
+  RelSymbol<ELFT> S = getSymbolForReloc(Obj, this->FileName, this->dumper(), R);
+  printRelocation(Obj, S.Sym, S.Name, R, IsRela);
 }
 
 template <class ELFT> void GNUStyle<ELFT>::printDynamic(const ELFO *Obj) {
@@ -5404,11 +5430,9 @@ template <class ELFT>
 void LLVMStyle<ELFT>::printDynamicRelocation(const ELFO *Obj, Elf_Rela Rel) {
   SmallString<32> RelocName;
   Obj->getRelocationTypeName(Rel.getType(Obj->isMips64EL()), RelocName);
-  std::string SymbolName;
-  uint32_t SymIndex = Rel.getSymbol(Obj->isMips64EL());
-  const Elf_Sym *Sym = this->dumper()->dynamic_symbols().begin() + SymIndex;
-  SymbolName = maybeDemangle(unwrapOrError(
-      this->FileName, Sym->getName(this->dumper()->getDynamicStringTable())));
+  std::string SymbolName =
+      getSymbolForReloc(Obj, this->FileName, this->dumper(), Rel).Name;
+
   if (opts::ExpandRelocs) {
     DictScope Group(W, "Relocation");
     W.printHex("Offset", Rel.r_offset);




More information about the llvm-commits mailing list