1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 03:02:36 +01:00

[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

llvm-svn: 370330
This commit is contained in:
George Rimar 2019-08-29 10:55:57 +00:00
parent fe2d85e28c
commit 2fdfc9c726
4 changed files with 91 additions and 12 deletions

View File

@ -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);
}

View File

@ -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:

View File

@ -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

View File

@ -3525,14 +3525,40 @@ void GNUStyle<ELFT>::printSectionMapping(const ELFO *Obj) {
}
}
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);