[llvm-readobj/elf] - Report warnings instead of errors when dumping broken stack sizes sections.

This replaces `reportError` calls with `reportUniqueWarning` and improves testing
for the code that is related to stack sizes dumping.

Differential revision: https://reviews.llvm.org/D86783
This commit is contained in:
Georgii Rymar 2020-08-28 16:38:18 +03:00
parent 03812041d8
commit 7de090a324
2 changed files with 167 additions and 73 deletions

View File

@ -176,14 +176,30 @@ Symbols:
Type: STT_FUNC Type: STT_FUNC
Binding: STB_GLOBAL Binding: STB_GLOBAL
## Check that we report an error when we find relocations whose offsets point outside ## Check that we report a warning when we find relocations whose offsets point outside
## of the .stack_sizes section. ## of the .stack_sizes section.
# RUN: yaml2obj --docnum=3 %s -o %t03 # RUN: yaml2obj --docnum=3 %s -o %t03
# RUN: not llvm-readelf --stack-sizes %t03 2>&1 | FileCheck %s --check-prefix=SHORT -DFILE=%t03 # RUN: llvm-readelf --stack-sizes %t03 2>&1 | FileCheck %s --check-prefix=SHORT-GNU -DFILE=%t03
# RUN: not llvm-readobj --stack-sizes %t03 2>&1 | FileCheck %s --check-prefix=SHORT -DFILE=%t03 # RUN: llvm-readobj --stack-sizes %t03 2>&1 | FileCheck %s --check-prefix=SHORT-LLVM -DFILE=%t03
# SHORT: error: '[[FILE]]': found invalid relocation offset into section .stack_sizes while trying to extract a stack size entry # SHORT-GNU: Stack Sizes:
# SHORT-GNU-NEXT: Size Function
# SHORT-GNU-NEXT: 8 foo
# SHORT-GNU-NEXT: warning: '[[FILE]]': found invalid relocation offset (0x1) into section .stack_sizes while trying to extract a stack size entry
# SHORT-GNU-NEXT: 8 foo
# SHORT-LLVM: StackSizes [
# SHORT-LLVM-NEXT: Entry {
# SHORT-LLVM-NEXT: Function: foo
# SHORT-LLVM-NEXT: Size: 0x8
# SHORT-LLVM-NEXT: }
# SHORT-LLVM-NEXT: warning: '[[FILE]]': found invalid relocation offset (0x1) into section .stack_sizes while trying to extract a stack size entry
# SHORT-LLVM-NEXT: Entry {
# SHORT-LLVM-NEXT: Function: foo
# SHORT-LLVM-NEXT: Size: 0x8
# SHORT-LLVM-NEXT: }
# SHORT-LLVM-NEXT: ]
--- !ELF --- !ELF
FileHeader: FileHeader:
@ -198,14 +214,24 @@ Sections:
Size: 16 Size: 16
- Name: .stack_sizes - Name: .stack_sizes
Type: SHT_PROGBITS Type: SHT_PROGBITS
Content: "00"
Link: .text Link: .text
Entries:
- Size: 0x8
- Name: .rela.stack_sizes - Name: .rela.stack_sizes
Type: SHT_RELA Type: SHT_RELA
Info: .stack_sizes Info: .stack_sizes
Relocations: Relocations:
- Offset: 1 - Offset: 0x0
Symbol: foo Symbol: foo
Type: R_X86_64_64
- Offset: 0x1
Symbol: foo
Type: R_X86_64_64
- Offset: 0x1
Symbol: foo
Type: R_X86_64_64
- Offset: 0x0
Symbol: foo
Type: R_X86_64_64 Type: R_X86_64_64
Symbols: Symbols:
- Name: foo - Name: foo
@ -271,45 +297,73 @@ Symbols:
Type: STT_FUNC Type: STT_FUNC
Binding: STB_GLOBAL Binding: STB_GLOBAL
## Check that we report an error when a stack sizes section ends with an incomplete stack size entry. ## Check that we report a warning when a stack sizes section ends with an incomplete stack size entry.
# RUN: yaml2obj --docnum=5 %s -o %t05 # RUN: yaml2obj --docnum=5 %s -o %t05
# RUN: not llvm-readelf --stack-sizes %t05 2>&1 | \ # RUN: llvm-readelf --stack-sizes %t05 2>&1 | \
# RUN: FileCheck %s --check-prefix=SUDDENEND -DFILE=%t05 # RUN: FileCheck %s --check-prefix=SUDDENEND-GNU -DFILE=%t05
# RUN: not llvm-readobj --stack-sizes %t05 2>&1 | \ # RUN: llvm-readobj --stack-sizes %t05 2>&1 | \
# RUN: FileCheck %s --check-prefix=SUDDENEND -DFILE=%t05 # RUN: FileCheck %s --check-prefix=SUDDENEND-LLVM -DFILE=%t05
# SUDDENEND: error: '[[FILE]]': section .stack_sizes ended while trying to extract a stack size entry # SUDDENEND-GNU: Stack Sizes:
# SUDDENEND-GNU-NEXT: Size Function
# SUDDENEND-GNU-NEXT: 8 foo
# SUDDENEND-GNU-NEXT: warning: '[[FILE]]': SHT_PROGBITS section with index 2 ended while trying to extract a stack size entry
# SUDDENEND-GNU-NEXT: 8 foo
# SUDDENEND-GNU-NEXT: warning: '[[FILE]]': SHT_PROGBITS section with index 3 ended while trying to extract a stack size entry
# SUDDENEND-LLVM: StackSizes [
# SUDDENEND-LLVM-NEXT: Entry {
# SUDDENEND-LLVM-NEXT: Function: foo
# SUDDENEND-LLVM-NEXT: Size: 0x8
# SUDDENEND-LLVM-NEXT: }
# SUDDENEND-LLVM-NEXT: warning: '[[FILE]]': SHT_PROGBITS section with index 2 ended while trying to extract a stack size entry
# SUDDENEND-LLVM-NEXT: Entry {
# SUDDENEND-LLVM-NEXT: Function: foo
# SUDDENEND-LLVM-NEXT: Size: 0x8
# SUDDENEND-LLVM-NEXT: }
# SUDDENEND-LLVM-NEXT: warning: '[[FILE]]': SHT_PROGBITS section with index 3 ended while trying to extract a stack size entry
# SUDDENEND-LLVM-NEXT: ]
--- !ELF --- !ELF
FileHeader: FileHeader:
Class: ELFCLASS64 Class: ELFCLASS64
Data: ELFDATA2LSB Data: ELFDATA2LSB
Type: ET_EXEC Type: ET_EXEC
Machine: EM_X86_64
Sections: Sections:
- Name: .text - Name: .text
Type: SHT_PROGBITS Type: SHT_PROGBITS
Flags: [SHF_ALLOC] - Name: .stack_sizes
Size: 16 Type: SHT_PROGBITS
- Name: .stack_sizes Link: .text
Type: SHT_PROGBITS Entries:
Content: "10000000" - Size: 0x8
Link: .text - Size: 0x10
## 0x11 == the normal size minus 1.
ShSize: 0x11
- Name: .stack_sizes (1)
Type: SHT_PROGBITS
Link: .text
Entries:
- Size: 0x8
- Size: 0x10
ShSize: 0x11
Symbols: Symbols:
- Name: foo - Name: foo
Section: .text Section: .text
Value: 0x10
Type: STT_FUNC Type: STT_FUNC
Binding: STB_GLOBAL
## Check that we report an invalid stack size, which is represented by a ULEB that ## Check that we report an invalid stack size, which is represented by a ULEB that
## ends in a byte with the high bit set. ## ends in a byte with the high bit set.
# RUN: yaml2obj --docnum=6 %s -o %t06 # RUN: yaml2obj --docnum=6 %s -o %t06
# RUN: not llvm-readelf --stack-sizes %t06 2>&1 | FileCheck %s --check-prefix=BADSIZE -DFILE=%t06 # RUN: llvm-readelf --stack-sizes %t06 2>&1 | FileCheck %s --check-prefix=BADSIZE -DFILE=%t06
# RUN: not llvm-readobj --stack-sizes %t06 2>&1 | FileCheck %s --check-prefix=BADSIZE -DFILE=%t06 # RUN: llvm-readobj --stack-sizes %t06 2>&1 | FileCheck %s --check-prefix=BADSIZE -DFILE=%t06
# BADSIZE: error: '[[FILE]]': could not extract a valid stack size in section .stack_sizes ## TODO: these messages should be improved to include section indices.
# BADSIZE: warning: '[[FILE]]': could not extract a valid stack size in section .stack_sizes
# BADSIZE: warning: '[[FILE]]': could not extract a valid stack size in section .stack_sizes
--- !ELF --- !ELF
FileHeader: FileHeader:
@ -325,6 +379,10 @@ Sections:
Type: SHT_PROGBITS Type: SHT_PROGBITS
Content: "100000000000000080" Content: "100000000000000080"
Link: .text Link: .text
- Name: .stack_sizes (1)
Type: SHT_PROGBITS
Content: "100000000000000080"
Link: .text
Symbols: Symbols:
- Name: foo - Name: foo
Section: .text Section: .text
@ -525,7 +583,7 @@ Sections:
Info: .stack_sizes Info: .stack_sizes
Relocations: Relocations:
- Offset: 0 - Offset: 0
Symbol: foo Symbol: foo
Type: R_X86_64_64 Type: R_X86_64_64
Symbols: Symbols:
- Name: foo - Name: foo
@ -533,14 +591,27 @@ Symbols:
Type: STT_OBJECT Type: STT_OBJECT
Binding: STB_GLOBAL Binding: STB_GLOBAL
## Check that we report an error when we find an unsupported relocation ## Check that we report a warning when we find an unsupported relocation
## in the section that contains the stack size entries' relocations. ## in the section that contains the stack size entries' relocations.
# RUN: yaml2obj --docnum=10 %s -o %t15 # RUN: yaml2obj --docnum=10 %s -o %t15
# RUN: not llvm-readelf --stack-sizes %t15 2>&1 | FileCheck %s --check-prefix=UNSUPPRELOC -DFILE=%t15 # RUN: llvm-readelf --stack-sizes %t15 2>&1 | FileCheck %s --check-prefix=UNSUPPRELOC-GNU -DFILE=%t15
# RUN: not llvm-readobj --stack-sizes %t15 2>&1 | FileCheck %s --check-prefix=UNSUPPRELOC -DFILE=%t15 # RUN: llvm-readobj --stack-sizes %t15 2>&1 | FileCheck %s --check-prefix=UNSUPPRELOC-LLVM -DFILE=%t15
# UNSUPPRELOC: error: '[[FILE]]': unsupported relocation type in section .rela.stack_sizes: R_X86_64_RELATIVE # UNSUPPRELOC-GNU: Stack Sizes:
# UNSUPPRELOC-GNU-NEXT: Size Function
# UNSUPPRELOC-GNU-NEXT: warning: '[[FILE]]': SHT_RELA section with index 3 contains an unsupported relocation with index 1: R_X86_64_RELATIVE
# UNSUPPRELOC-GNU-NEXT: 0 foo
# UNSUPPRELOC-GNU-NEXT: warning: '[[FILE]]': SHT_RELA section with index 3 contains an unsupported relocation with index 3: R_X86_64_RELATIVE
# UNSUPPRELOC-LLVM: StackSizes [
# UNSUPPRELOC-LLVM-NEXT: warning: '[[FILE]]': SHT_RELA section with index 3 contains an unsupported relocation with index 1: R_X86_64_RELATIVE
# UNSUPPRELOC-LLVM-NEXT: Entry {
# UNSUPPRELOC-LLVM-NEXT: Function: foo
# UNSUPPRELOC-LLVM-NEXT: Size: 0x0
# UNSUPPRELOC-LLVM-NEXT: }
# UNSUPPRELOC-LLVM-NEXT: warning: '[[FILE]]': SHT_RELA section with index 3 contains an unsupported relocation with index 3: R_X86_64_RELATIVE
# UNSUPPRELOC-LLVM-NEXT: ]
--- !ELF --- !ELF
FileHeader: FileHeader:
@ -555,13 +626,20 @@ Sections:
- Name: .stack_sizes - Name: .stack_sizes
Type: SHT_PROGBITS Type: SHT_PROGBITS
Link: .text Link: .text
Entries: [] Entries:
- Size: 0
- Name: .rela.stack_sizes - Name: .rela.stack_sizes
Type: SHT_RELA Type: SHT_RELA
Info: .stack_sizes Info: .stack_sizes
Relocations: Relocations:
- Offset: 0 - Offset: 0
Symbol: foo Symbol: foo
Type: R_X86_64_RELATIVE
- Offset: 0
Symbol: foo
Type: R_X86_64_64
- Offset: 0
Symbol: foo
Type: R_X86_64_RELATIVE Type: R_X86_64_RELATIVE
Symbols: Symbols:
- Name: foo - Name: foo
@ -648,14 +726,14 @@ Symbols:
Type: STT_FUNC Type: STT_FUNC
Binding: STB_GLOBAL Binding: STB_GLOBAL
## Check that we report an error when we are unable to resolve a relocation for a given ELF architecture. ## Check that we report a warning when we are unable to resolve a relocation for a given ELF architecture.
## Here we have a 64-bit relocation used in a 32-bit object. ## Here we have a 64-bit relocation used in a 32-bit object.
# RUN: yaml2obj --docnum=12 %s -o %t17 # RUN: yaml2obj --docnum=12 %s -o %t17
# RUN: not llvm-readelf --stack-sizes %t17 2>&1 | FileCheck %s -DFILE=%t17 --check-prefix=UNSUPPRELOC2 # RUN: llvm-readelf --stack-sizes %t17 2>&1 | FileCheck %s -DFILE=%t17 --check-prefix=UNSUPPRELOC2
# RUN: not llvm-readobj --stack-sizes %t17 2>&1 | FileCheck %s -DFILE=%t17 --check-prefix=UNSUPPRELOC2 # RUN: llvm-readobj --stack-sizes %t17 2>&1 | FileCheck %s -DFILE=%t17 --check-prefix=UNSUPPRELOC2
# UNSUPPRELOC2: error: '[[FILE]]': unsupported relocation type in section .rela.stack_sizes: R_X86_64_64 # UNSUPPRELOC2: warning: '[[FILE]]': SHT_RELA section with index 2 contains an unsupported relocation with index 1: R_X86_64_64
--- !ELF --- !ELF
FileHeader: FileHeader:
@ -674,15 +752,18 @@ Sections:
- Offset: 0 - Offset: 0
Type: R_X86_64_64 Type: R_X86_64_64
## Check we report an error when dumping stack sizes if the relocated section ## Check we report a warning when dumping stack sizes if the relocated section
## identified by the sh_info field is invalid. Here the sh_info value is larger than ## identified by the sh_info field is invalid. Here the sh_info value is larger than
## the number of sections. ## the number of sections.
# RUN: yaml2obj --docnum=13 %s -o %t18 # RUN: yaml2obj --docnum=13 %s -o %t18
# RUN: not llvm-readelf --stack-sizes %t18 2>&1 | FileCheck %s -DFILE=%t18 --check-prefix=INVALID-TARGET # RUN: llvm-readelf --stack-sizes %t18 2>&1 | \
# RUN: not llvm-readobj --stack-sizes %t18 2>&1 | FileCheck %s -DFILE=%t18 --check-prefix=INVALID-TARGET # RUN: FileCheck %s --implicit-check-not="warning:" -DFILE=%t18 --check-prefix=INVALID-TARGET
# RUN: llvm-readobj --stack-sizes %t18 2>&1 | \
# RUN: FileCheck %s --implicit-check-not="warning:" -DFILE=%t18 --check-prefix=INVALID-TARGET
# INVALID-TARGET: error: '[[FILE]]': .rela.stack_sizes: failed to get a relocated section: invalid section index: 255 # INVALID-TARGET: warning: '[[FILE]]': SHT_RELA section with index 1: failed to get a relocated section: invalid section index: 255
# INVALID-TARGET: warning: '[[FILE]]': SHT_RELA section with index 2: failed to get a relocated section: invalid section index: 255
--- !ELF --- !ELF
FileHeader: FileHeader:
@ -695,3 +776,8 @@ Sections:
Link: 0 Link: 0
Info: 0xFF Info: 0xFF
Relocations: [] Relocations: []
- Name: .rela.stack_sizes (1)
Type: SHT_RELA
Link: 0
Info: 0xFF
Relocations: []

View File

@ -5691,12 +5691,14 @@ void DumpStyle<ELFT>::printFunctionStackSize(const ELFObjectFile<ELFT> *Obj,
uint64_t StackSize = Data.getULEB128(Offset); uint64_t StackSize = Data.getULEB128(Offset);
// getULEB128() does not advance Offset if it is not able to extract a valid // getULEB128() does not advance Offset if it is not able to extract a valid
// integer. // integer.
if (*Offset == PrevOffset) if (*Offset == PrevOffset) {
reportError( reportWarning(
createStringError(object_error::parse_failed, createStringError(object_error::parse_failed,
"could not extract a valid stack size in section %s", "could not extract a valid stack size in section %s",
SectionName.data()), SectionName.data()),
Obj->getFileName()); Obj->getFileName());
return;
}
printStackSizeEntry(StackSize, FuncName); printStackSizeEntry(StackSize, FuncName);
} }
@ -5750,13 +5752,14 @@ void DumpStyle<ELFT>::printStackSize(const ELFObjectFile<ELFT> *Obj,
} }
uint64_t Offset = Reloc.getOffset(); uint64_t Offset = Reloc.getOffset();
if (!Data.isValidOffsetForDataOfSize(Offset, sizeof(Elf_Addr) + 1)) if (!Data.isValidOffsetForDataOfSize(Offset, sizeof(Elf_Addr) + 1)) {
reportError( reportUniqueWarning(createStringError(
createStringError(object_error::parse_failed, object_error::parse_failed,
"found invalid relocation offset into section %s " "found invalid relocation offset (0x" + Twine::utohexstr(Offset) +
"while trying to extract a stack size entry", ") into section " + StackSizeSectionName +
StackSizeSectionName.data()), " while trying to extract a stack size entry"));
FileStr); return;
}
uint64_t Addend = Data.getAddress(&Offset); uint64_t Addend = Data.getAddress(&Offset);
uint64_t SymValue = Resolver(Reloc, RelocSymValue, Addend); uint64_t SymValue = Resolver(Reloc, RelocSymValue, Addend);
@ -5770,7 +5773,6 @@ void DumpStyle<ELFT>::printNonRelocatableStackSizes(
// This function ignores potentially erroneous input, unless it is directly // This function ignores potentially erroneous input, unless it is directly
// related to stack size reporting. // related to stack size reporting.
const ELFFile<ELFT> *EF = Obj->getELFFile(); const ELFFile<ELFT> *EF = Obj->getELFFile();
StringRef FileStr = Obj->getFileName();
for (const SectionRef &Sec : Obj->sections()) { for (const SectionRef &Sec : Obj->sections()) {
StringRef SectionName = getSectionName(Sec); StringRef SectionName = getSectionName(Sec);
if (SectionName != ".stack_sizes") if (SectionName != ".stack_sizes")
@ -5785,12 +5787,11 @@ void DumpStyle<ELFT>::printNonRelocatableStackSizes(
// The function address is followed by a ULEB representing the stack // The function address is followed by a ULEB representing the stack
// size. Check for an extra byte before we try to process the entry. // size. Check for an extra byte before we try to process the entry.
if (!Data.isValidOffsetForDataOfSize(Offset, sizeof(Elf_Addr) + 1)) { if (!Data.isValidOffsetForDataOfSize(Offset, sizeof(Elf_Addr) + 1)) {
reportError( reportUniqueWarning(createStringError(
createStringError( object_error::parse_failed,
object_error::parse_failed, describe(EF, *ElfSec) +
"section %s ended while trying to extract a stack size entry", " ended while trying to extract a stack size entry"));
SectionName.data()), break;
FileStr);
} }
uint64_t SymValue = Data.getAddress(&Offset); uint64_t SymValue = Data.getAddress(&Offset);
printFunctionStackSize(Obj, SymValue, /*FunctionSec=*/None, SectionName, printFunctionStackSize(Obj, SymValue, /*FunctionSec=*/None, SectionName,
@ -5832,12 +5833,14 @@ void DumpStyle<ELFT>::printRelocatableStackSizes(
continue; continue;
Expected<section_iterator> RelSecOrErr = Sec.getRelocatedSection(); Expected<section_iterator> RelSecOrErr = Sec.getRelocatedSection();
if (!RelSecOrErr) if (!RelSecOrErr) {
reportError(createStringError(object_error::parse_failed, reportUniqueWarning(
"%s: failed to get a relocated section: %s", createStringError(object_error::parse_failed,
SectionName.data(), describe(Obj->getELFFile(), *ElfSec) +
toString(RelSecOrErr.takeError()).c_str()), ": failed to get a relocated section: " +
Obj->getFileName()); toString(RelSecOrErr.takeError())));
continue;
}
const Elf_Shdr *ContentsSec = const Elf_Shdr *ContentsSec =
Obj->getSection((*RelSecOrErr)->getRawDataRefImpl()); Obj->getSection((*RelSecOrErr)->getRawDataRefImpl());
@ -5881,14 +5884,19 @@ void DumpStyle<ELFT>::printRelocatableStackSizes(
std::tie(IsSupportedFn, Resolver) = getRelocationResolver(*Obj); std::tie(IsSupportedFn, Resolver) = getRelocationResolver(*Obj);
auto Contents = unwrapOrError(this->FileName, StackSizesSec.getContents()); auto Contents = unwrapOrError(this->FileName, StackSizesSec.getContents());
DataExtractor Data(Contents, Obj->isLittleEndian(), sizeof(Elf_Addr)); DataExtractor Data(Contents, Obj->isLittleEndian(), sizeof(Elf_Addr));
size_t I = 0;
for (const RelocationRef &Reloc : RelocSec.relocations()) { for (const RelocationRef &Reloc : RelocSec.relocations()) {
if (!IsSupportedFn || !IsSupportedFn(Reloc.getType())) ++I;
reportError(createStringError( if (!IsSupportedFn || !IsSupportedFn(Reloc.getType())) {
object_error::parse_failed, const Elf_Shdr *RelocSecShdr =
"unsupported relocation type in section %s: %s", Obj->getSection(RelocSec.getRawDataRefImpl());
getSectionName(RelocSec).data(), reportUniqueWarning(createStringError(
EF->getRelocationTypeName(Reloc.getType()).data()), object_error::parse_failed,
Obj->getFileName()); describe(EF, *RelocSecShdr) +
" contains an unsupported relocation with index " + Twine(I) +
": " + EF->getRelocationTypeName(Reloc.getType())));
continue;
}
this->printStackSize(Obj, Reloc, FunctionSec, StackSizeSectionName, this->printStackSize(Obj, Reloc, FunctionSec, StackSizeSectionName,
Resolver, Data); Resolver, Data);
} }