mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 03:02:36 +01:00
[llvm-readobj] - Don't crash when dumping invalid dynamic relocation.
Currently when we dump dynamic relocation with use of DT_RELA/DT_RELASZ/DT_RELAENT tags, we crash when a symbol index is larger than the number of dynamic symbols or when there is no dynamic symbol table. This patch adds test cases and fixes the issues. Differential revision: https://reviews.llvm.org/D73560
This commit is contained in:
parent
d026cc2d7f
commit
d3e0d6fc26
@ -373,3 +373,102 @@ ProgramHeaders:
|
||||
Sections:
|
||||
- Section: .rela.plt
|
||||
- Section: .dynamic
|
||||
|
||||
## Show we print a warning when dumping dynamic relocations if there is no dynamic symbol table.
|
||||
# RUN: yaml2obj --docnum=11 %s -o %t11
|
||||
# RUN: llvm-readobj --dyn-relocations %t11 2>&1 | FileCheck %s -DFILE=%t11 --check-prefix=LLVM-NO-DYNSYM
|
||||
# RUN: llvm-readelf --dyn-relocations %t11 2>&1 | FileCheck %s -DFILE=%t11 --check-prefix=GNU-NO-DYNSYM
|
||||
|
||||
# LLVM-NO-DYNSYM: Dynamic Relocations {
|
||||
# LLVM-NO-DYNSYM-NEXT: warning: '[[FILE]]': unable to get name of the dynamic symbol with index 0: no dynamic symbol table found
|
||||
# LLVM-NO-DYNSYM-NEXT: 0x0 R_X86_64_NONE <corrupt> 0x0
|
||||
# LLVM-NO-DYNSYM-NEXT: warning: '[[FILE]]': unable to get name of the dynamic symbol with index 1: no dynamic symbol table found
|
||||
# LLVM-NO-DYNSYM-NEXT: 0x0 R_X86_64_NONE <corrupt> 0x0
|
||||
# LLVM-NO-DYNSYM-NEXT: }
|
||||
|
||||
# GNU-NO-DYNSYM: 'RELA' relocation section at offset 0x78 contains 48 bytes:
|
||||
# GNU-NO-DYNSYM-NEXT: Offset Info Type Symbol's Value Symbol's Name + Addend
|
||||
# GNU-NO-DYNSYM-NEXT: warning: '[[FILE]]': unable to get name of the dynamic symbol with index 0: no dynamic symbol table found
|
||||
# GNU-NO-DYNSYM-NEXT: 0000000000000000 0000000000000000 R_X86_64_NONE <corrupt> + 0
|
||||
# GNU-NO-DYNSYM-NEXT: warning: '[[FILE]]': unable to get name of the dynamic symbol with index 1: no dynamic symbol table found
|
||||
# GNU-NO-DYNSYM-NEXT: 0000000000000000 0000000100000000 R_X86_64_NONE <corrupt> + 0
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_DYN
|
||||
Machine: EM_X86_64
|
||||
Sections:
|
||||
- Name: .rela.dyn
|
||||
Type: SHT_RELA
|
||||
Relocations:
|
||||
- Offset: 0x0
|
||||
Type: R_X86_64_NONE
|
||||
- Offset: 0x0
|
||||
Type: R_X86_64_NONE
|
||||
Symbol: 0x1
|
||||
- Name: .dynamic
|
||||
Type: SHT_DYNAMIC
|
||||
Entries:
|
||||
- Tag: DT_RELA
|
||||
Value: 0x0
|
||||
- Tag: DT_RELASZ
|
||||
Value: 0x30
|
||||
- Tag: DT_RELAENT
|
||||
Value: 0x18
|
||||
- Tag: DT_NULL
|
||||
Value: 0x0
|
||||
ProgramHeaders:
|
||||
- Type: PT_LOAD
|
||||
Sections:
|
||||
- Section: .rela.dyn
|
||||
- Section: .dynamic
|
||||
|
||||
## Show we print a warning when the symbol index of a dynamic relocation is too
|
||||
## large (goes past the end of the dynamic symbol table).
|
||||
# RUN: yaml2obj --docnum=12 %s -o %t12
|
||||
# RUN: llvm-readobj --dyn-relocations %t12 2>&1 | FileCheck %s -DFILE=%t12 --check-prefix=LLVM-INVALID-DYNSYM
|
||||
# RUN: llvm-readelf --dyn-relocations %t12 2>&1 | FileCheck %s -DFILE=%t12 --check-prefix=GNU-INVALID-DYNSYM
|
||||
|
||||
# LLVM-INVALID-DYNSYM: Dynamic Relocations {
|
||||
# LLVM-INVALID-DYNSYM-NEXT: warning: '[[FILE]]': unable to get name of the dynamic symbol with index 2: index is greater than or equal to the number of dynamic symbols (2)
|
||||
# LLVM-INVALID-DYNSYM-NEXT: 0x0 R_X86_64_NONE <corrupt> 0x0
|
||||
# LLVM-INVALID-DYNSYM-NEXT: }
|
||||
|
||||
# GNU-INVALID-DYNSYM: 'RELA' relocation section at offset 0x78 contains 24 bytes:
|
||||
# GNU-INVALID-DYNSYM-NEXT: Offset Info Type Symbol's Value Symbol's Name + Addend
|
||||
# GNU-INVALID-DYNSYM-NEXT: warning: '[[FILE]]': unable to get name of the dynamic symbol with index 2: index is greater than or equal to the number of dynamic symbols (2)
|
||||
# GNU-INVALID-DYNSYM-NEXT: 0000000000000000 0000000200000000 R_X86_64_NONE <corrupt> + 0
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_DYN
|
||||
Machine: EM_X86_64
|
||||
Sections:
|
||||
- Name: .rela.dyn
|
||||
Type: SHT_RELA
|
||||
Relocations:
|
||||
- Offset: 0x0
|
||||
Type: R_X86_64_NONE
|
||||
Symbol: 0x2
|
||||
- Name: .dynamic
|
||||
Type: SHT_DYNAMIC
|
||||
Entries:
|
||||
- Tag: DT_RELA
|
||||
Value: 0x0
|
||||
- Tag: DT_RELASZ
|
||||
Value: 0x18
|
||||
- Tag: DT_RELAENT
|
||||
Value: 0x18
|
||||
- Tag: DT_NULL
|
||||
Value: 0x0
|
||||
DynamicSymbols:
|
||||
- Name: foo
|
||||
ProgramHeaders:
|
||||
- Type: PT_LOAD
|
||||
Sections:
|
||||
- Section: .rela.dyn
|
||||
- Section: .dynamic
|
||||
|
@ -0,0 +1,69 @@
|
||||
## Test that we are able to print dynamic relocations with --dyn-relocations
|
||||
## even when there are no section headers.
|
||||
|
||||
# RUN: yaml2obj %s -o %t
|
||||
# RUN: llvm-readobj --dyn-relocations %t 2>&1 \
|
||||
# RUN: | FileCheck %s -DFILE=%t --implicit-check-not="warning:" --check-prefix=LLVM-NO-SEC-TABLE
|
||||
# RUN: llvm-readelf --dyn-relocations %t 2>&1 \
|
||||
# RUN: | FileCheck %s -DFILE=%t --implicit-check-not="warning:" --check-prefix=GNU-NO-SEC-TABLE
|
||||
|
||||
# LLVM-NO-SEC-TABLE: Dynamic Relocations {
|
||||
# LLVM-NO-SEC-TABLE-NEXT: 0x0 R_X86_64_NONE foo 0x0
|
||||
# LLVM-NO-SEC-TABLE-NEXT: }
|
||||
|
||||
# GNU-NO-SEC-TABLE: 'RELA' relocation section at offset 0xb0 contains 24 bytes:
|
||||
# GNU-NO-SEC-TABLE-NEXT: Offset Info Type Symbol's Value Symbol's Name + Addend
|
||||
# GNU-NO-SEC-TABLE-NEXT: 0000000000000000 0000000100000000 R_X86_64_NONE 0000000000000000 foo + 0
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_DYN
|
||||
Machine: EM_X86_64
|
||||
## We simulate no section header table by
|
||||
## overriding the ELF header properties.
|
||||
SHOff: 0x0
|
||||
SHNum: 0x0
|
||||
Sections:
|
||||
- Name: .rela.dyn
|
||||
Type: SHT_RELA
|
||||
Relocations:
|
||||
- Offset: 0x0
|
||||
Type: R_X86_64_NONE
|
||||
Symbol: 0x1
|
||||
- Name: .dynamic
|
||||
Type: SHT_DYNAMIC
|
||||
Entries:
|
||||
- Tag: DT_RELA
|
||||
Value: 0x0
|
||||
- Tag: DT_RELASZ
|
||||
Value: 0x18
|
||||
- Tag: DT_RELAENT
|
||||
Value: 0x18
|
||||
## Offset of .dynsym is 0x138. Offset of PT_LOAD is 0xb0.
|
||||
## 0x138 - 0xb0 == 0x88
|
||||
- Tag: DT_SYMTAB
|
||||
Value: 0x88
|
||||
- Tag: DT_STRSZ
|
||||
Value: 0x5
|
||||
## Offset of .dynstr is 0x19f. Offset of PT_LOAD is 0xb0.
|
||||
## 0x19f - 0xb0 == 0xef
|
||||
- Tag: DT_STRTAB
|
||||
Value: 0xef
|
||||
- Tag: DT_NULL
|
||||
Value: 0x0
|
||||
- Name: .dynsym
|
||||
Type: SHT_DYNSYM
|
||||
DynamicSymbols:
|
||||
- Name: foo
|
||||
ProgramHeaders:
|
||||
- Type: PT_LOAD
|
||||
Sections:
|
||||
- Section: .rela.dyn
|
||||
- Section: .dynamic
|
||||
Section: .dynsym
|
||||
Section: .dynstr
|
||||
- Type: PT_DYNAMIC
|
||||
Sections:
|
||||
- Section: .dynamic
|
@ -4030,21 +4030,35 @@ 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 {
|
||||
auto WarnAndReturn = [&](const typename ELFT::Sym *Sym,
|
||||
const Twine &Reason) -> RelSymbol<ELFT> {
|
||||
reportWarning(
|
||||
createError("unable to get name of the dynamic symbol with index " +
|
||||
Twine(SymIndex) + ": " + toString(ErrOrName.takeError())),
|
||||
Twine(SymIndex) + ": " + Reason),
|
||||
FileName);
|
||||
Name = "<corrupt>";
|
||||
}
|
||||
return {Sym, "<corrupt>"};
|
||||
};
|
||||
|
||||
return {Sym, std::move(Name)};
|
||||
ArrayRef<typename ELFT::Sym> Symbols = Dumper->dynamic_symbols();
|
||||
const typename ELFT::Sym *FirstSym = Symbols.begin();
|
||||
if (!FirstSym)
|
||||
return WarnAndReturn(nullptr, "no dynamic symbol table found");
|
||||
|
||||
// We might have an object without a section header. In this case the size of
|
||||
// Symbols is zero, because there is no way to know the size of the dynamic
|
||||
// table. We should allow this case and not print a warning.
|
||||
if (!Symbols.empty() && SymIndex >= Symbols.size())
|
||||
return WarnAndReturn(
|
||||
nullptr,
|
||||
"index is greater than or equal to the number of dynamic symbols (" +
|
||||
Twine(Symbols.size()) + ")");
|
||||
|
||||
const typename ELFT::Sym *Sym = FirstSym + SymIndex;
|
||||
Expected<StringRef> ErrOrName = Sym->getName(Dumper->getDynamicStringTable());
|
||||
if (!ErrOrName)
|
||||
return WarnAndReturn(Sym, toString(ErrOrName.takeError()));
|
||||
|
||||
return {Sym, maybeDemangle(*ErrOrName)};
|
||||
}
|
||||
} // namespace
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user