[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