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:
parent
fe2d85e28c
commit
2fdfc9c726
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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:
|
||||
|
51
test/tools/llvm-readobj/elf-broken-dynamic-reloc-name.test
Normal file
51
test/tools/llvm-readobj/elf-broken-dynamic-reloc-name.test
Normal 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
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user