1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-26 12:43:36 +01:00

[llvm-readobj/elf] - Refine the implementation of "printFunctionStackSize".

This rewrites the logic to get rid of "ELFSymbolRef" API where possible.
This allowed to handle possible errors better, improve warnings reported and add new ones.
Also 'reportWarning' was replaced with 'reportUniqueWarning'

Differential revision: https://reviews.llvm.org/D92545
This commit is contained in:
Georgii Rymar 2020-12-01 17:00:03 +03:00
parent 4b64a9ef7d
commit a9fdb4b116
3 changed files with 160 additions and 52 deletions

View File

@ -246,6 +246,10 @@ public:
return SectionRef(toDRI(Sec), this); return SectionRef(toDRI(Sec), this);
} }
ELFSymbolRef toSymbolRef(const Elf_Shdr *SymTable, unsigned SymbolNum) const {
return ELFSymbolRef({toDRI(SymTable, SymbolNum), this});
}
bool IsContentValid() const { return ContentValid; } bool IsContentValid() const { return ContentValid; }
private: private:

View File

@ -74,10 +74,14 @@ Sections:
- Offset: 0 - Offset: 0
Symbol: separate_text_section_baz Symbol: separate_text_section_baz
Type: R_X86_64_64 Type: R_X86_64_64
- Name: .symtab
Type: SHT_SYMTAB
ShOffset: [[SYMTABOFFSET=<none>]]
Symbols: Symbols:
- Name: separate_text_section_baz - Name: separate_text_section_baz
Section: .text.baz Section: [[SEC1=.text.baz]]
Type: STT_FUNC Type: STT_FUNC
Index: [[SEC1INDEX=<none>]]
- Name: .text - Name: .text
Section: .text Section: .text
Type: STT_SECTION Type: STT_SECTION
@ -91,6 +95,86 @@ Symbols:
Type: STT_FUNC Type: STT_FUNC
Binding: STB_GLOBAL Binding: STB_GLOBAL
## Check that we report a warning when we are unable to read
## the symbol table when dumping stack sizes.
# RUN: yaml2obj --docnum=1 %s -DSYMTABOFFSET=0xffffeeee -o %t01.broken.symtab
# RUN: llvm-readelf --stack-sizes %t01.broken.symtab 2>&1 | \
# RUN: FileCheck %s -DFILE=%t01.broken.symtab --check-prefix=SYMTAB-GNU --implicit-check-not=warning:
# RUN: llvm-readobj --stack-sizes %t01.broken.symtab 2>&1 | \
# RUN: FileCheck %s -DFILE=%t01.broken.symtab --check-prefix=SYMTAB-LLVM --implicit-check-not=warning:
# SYMTAB-GNU: Stack Sizes:
# SYMTAB-GNU-NEXT: Size Function
# SYMTAB-GNU-NEXT: warning: '[[FILE]]': unable to get the target of relocation with index 1 in SHT_RELA section with index 5: unable to access section [index 7] data at 0xffffef36: offset goes past the end of file
# SYMTAB-GNU-NEXT: warning: '[[FILE]]': unable to read the symbol table: section [index 7] has a sh_offset (0xffffeeee) + sh_size (0x78) that is greater than the file size (0x450)
# SYMTAB-GNU-NEXT: warning: '[[FILE]]': could not identify function symbol for stack size entry in SHT_PROGBITS section with index 3
# SYMTAB-GNU-NEXT: 16 ?
# SYMTAB-GNU-NEXT: warning: '[[FILE]]': unable to get the target of relocation with index 2 in SHT_RELA section with index 5: unable to access section [index 7] data at 0xffffef1e: offset goes past the end of file
# SYMTAB-GNU-NEXT: 32 ?
# SYMTAB-GNU-NEXT: warning: '[[FILE]]': unable to get the target of relocation with index 1 in SHT_RELA section with index 6: unable to access section [index 7] data at 0xffffef06: offset goes past the end of file
# SYMTAB-GNU-NEXT: warning: '[[FILE]]': could not identify function symbol for stack size entry in SHT_PROGBITS section with index 4
# SYMTAB-GNU-NEXT: 8 ?
# SYMTAB-LLVM: StackSizes [
# SYMTAB-LLVM-NEXT: warning: '[[FILE]]': unable to get the target of relocation with index 1 in SHT_RELA section with index 5: unable to access section [index 7] data at 0xffffef36: offset goes past the end of file
# SYMTAB-LLVM-NEXT: warning: '[[FILE]]': unable to read the symbol table: section [index 7] has a sh_offset (0xffffeeee) + sh_size (0x78) that is greater than the file size (0x450)
# SYMTAB-LLVM-NEXT: warning: '[[FILE]]': could not identify function symbol for stack size entry in SHT_PROGBITS section with index 3
# SYMTAB-LLVM-NEXT: Entry {
# SYMTAB-LLVM-NEXT: Function: ?
# SYMTAB-LLVM-NEXT: Size: 0x10
# SYMTAB-LLVM-NEXT: }
# SYMTAB-LLVM-NEXT: warning: '[[FILE]]': unable to get the target of relocation with index 2 in SHT_RELA section with index 5: unable to access section [index 7] data at 0xffffef1e: offset goes past the end of file
# SYMTAB-LLVM-NEXT: Entry {
# SYMTAB-LLVM-NEXT: Function: ?
# SYMTAB-LLVM-NEXT: Size: 0x20
# SYMTAB-LLVM-NEXT: }
# SYMTAB-LLVM-NEXT: warning: '[[FILE]]': unable to get the target of relocation with index 1 in SHT_RELA section with index 6: unable to access section [index 7] data at 0xffffef06: offset goes past the end of file
# SYMTAB-LLVM-NEXT: warning: '[[FILE]]': could not identify function symbol for stack size entry in SHT_PROGBITS section with index 4
# SYMTAB-LLVM-NEXT: Entry {
# SYMTAB-LLVM-NEXT: Function: ?
# SYMTAB-LLVM-NEXT: Size: 0x8
# SYMTAB-LLVM-NEXT: }
# SYMTAB-LLVM-NEXT: ]
## In this case we have a function symbol with an invalid section index.
## Document what we dump.
# RUN: yaml2obj --docnum=1 %s -DSEC1="<none>" -DSEC1INDEX=0xFF -o %t01.broken.sym
# RUN: llvm-readelf --stack-sizes %t01.broken.sym 2>&1 | \
# RUN: FileCheck %s -DFILE=%t01.broken.sym --check-prefix=SYM-GNU --implicit-check-not=warning:
# RUN: llvm-readobj --stack-sizes %t01.broken.sym 2>&1 | \
# RUN: FileCheck %s -DFILE=%t01.broken.sym --check-prefix=SYM-LLVM --implicit-check-not=warning:
# SYM-GNU: Stack Sizes:
# SYM-GNU-NEXT: Size Function
# SYM-GNU-NEXT: warning: '[[FILE]]': unable to get address of symbol 'separate_text_section_baz': invalid section index: 255
# SYM-GNU-NEXT: warning: '[[FILE]]': could not identify function symbol for stack size entry in SHT_PROGBITS section with index 3
# SYM-GNU-NEXT: 16 ?
# SYM-GNU-NEXT: 32 ?
# SYM-GNU-NEXT: warning: '[[FILE]]': cannot identify the section for relocation symbol 'separate_text_section_baz': invalid section index: 255
# SYM-GNU-NEXT: warning: '[[FILE]]': could not identify function symbol for stack size entry in SHT_PROGBITS section with index 4
# SYM-GNU-NEXT: 8 ?
# SYM-LLVM: StackSizes [
# SYM-LLVM-NEXT: warning: '[[FILE]]': unable to get address of symbol 'separate_text_section_baz': invalid section index: 255
# SYM-LLVM-NEXT: warning: '[[FILE]]': could not identify function symbol for stack size entry in SHT_PROGBITS section with index 3
# SYM-LLVM-NEXT: Entry {
# SYM-LLVM-NEXT: Function: ?
# SYM-LLVM-NEXT: Size: 0x10
# SYM-LLVM-NEXT: }
# SYM-LLVM-NEXT: Entry {
# SYM-LLVM-NEXT: Function: ?
# SYM-LLVM-NEXT: Size: 0x20
# SYM-LLVM-NEXT: }
# SYM-LLVM-NEXT: warning: '[[FILE]]': cannot identify the section for relocation symbol 'separate_text_section_baz': invalid section index: 255
# SYM-LLVM-NEXT: warning: '[[FILE]]': could not identify function symbol for stack size entry in SHT_PROGBITS section with index 4
# SYM-LLVM-NEXT: Entry {
# SYM-LLVM-NEXT: Function: ?
# SYM-LLVM-NEXT: Size: 0x8
# SYM-LLVM-NEXT: }
# SYM-LLVM-NEXT: ]
## Check that we correctly report the stack sizes in an executable (non-relocatable) ## Check that we correctly report the stack sizes in an executable (non-relocatable)
## object file. This also shows that the sh_link field is ignored in this situation ## object file. This also shows that the sh_link field is ignored in this situation
## without warning. ## without warning.
@ -361,8 +445,8 @@ Symbols:
# RUN: 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: 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: warning: '[[FILE]]': could not extract a valid stack size in SHT_PROGBITS section with index 2 # BADSIZE: warning: '[[FILE]]': could not extract a valid stack size from SHT_PROGBITS section with index 2
# BADSIZE: warning: '[[FILE]]': could not extract a valid stack size in SHT_PROGBITS section with index 3 # BADSIZE: warning: '[[FILE]]': could not extract a valid stack size from SHT_PROGBITS section with index 3
--- !ELF --- !ELF
FileHeader: FileHeader:
@ -402,25 +486,32 @@ Symbols:
# BADSECTION-OUT-GNU: Stack Sizes: # BADSECTION-OUT-GNU: Stack Sizes:
# BADSECTION-OUT-GNU-NEXT: Size Function # BADSECTION-OUT-GNU-NEXT: Size Function
# BADSECTION-OUT-GNU-NEXT: warning: '[[FILE]]': cannot identify the section for relocation symbol '_Z3foof': invalid section index: 10 # BADSECTION-OUT-GNU-NEXT: warning: '[[FILE]]': cannot identify the section for relocation symbol '_Z3foof': invalid section index: 10
# BADSECTION-OUT-GNU-NEXT: warning: '[[FILE]]': could not identify function symbol for stack size entry # BADSECTION-OUT-GNU-NEXT: warning: '[[FILE]]': unable to get address of symbol '_Z3foof': invalid section index: 10
# BADSECTION-OUT-GNU-NEXT: warning: '[[FILE]]': could not identify function symbol for stack size entry in SHT_PROGBITS section with index 2
# BADSECTION-OUT-GNU-NEXT: 8 ? # BADSECTION-OUT-GNU-NEXT: 8 ?
# BADSECTION-OUT-GNU-NEXT: warning: '[[FILE]]': unable to get the target of relocation with index 2 in SHT_RELA section with index 3: unable to access section [index 4] data at 0x1880: offset goes past the end of file # BADSECTION-OUT-GNU-NEXT: warning: '[[FILE]]': unable to get the target of relocation with index 2 in SHT_RELA section with index 3: unable to access section [index 4] data at 0x18a0: offset goes past the end of file
# BADSECTION-OUT-GNU-NEXT: warning: '[[FILE]]': could not identify function symbol for stack size entry # BADSECTION-OUT-GNU-NEXT: 22 ?
# BADSECTION-OUT-GNU-NEXT: 22 ? # BADSECTION-OUT-GNU-NEXT: warning: '[[FILE]]': unable to get the target of relocation with index 3 in SHT_RELA section with index 3: unable to access section [index 4] data at 0x18a0: offset goes past the end of file
# BADSECTION-OUT-GNU-NEXT: 36 ?
# BADSECTION-OUT-LLVM: StackSizes [ # BADSECTION-OUT-LLVM: StackSizes [
# BADSECTION-OUT-LLVM-NEXT: warning: '[[FILE]]': cannot identify the section for relocation symbol '_Z3foof': invalid section index: 10 # BADSECTION-OUT-LLVM-NEXT: warning: '[[FILE]]': cannot identify the section for relocation symbol '_Z3foof': invalid section index: 10
# BADSECTION-OUT-LLVM-NEXT: warning: '[[FILE]]': could not identify function symbol for stack size entry # BADSECTION-OUT-LLVM-NEXT: warning: '[[FILE]]': unable to get address of symbol '_Z3foof': invalid section index: 10
# BADSECTION-OUT-LLVM-NEXT: warning: '[[FILE]]': could not identify function symbol for stack size entry in SHT_PROGBITS section with index 2
# BADSECTION-OUT-LLVM-NEXT: Entry { # BADSECTION-OUT-LLVM-NEXT: Entry {
# BADSECTION-OUT-LLVM-NEXT: Function: ? # BADSECTION-OUT-LLVM-NEXT: Function: ?
# BADSECTION-OUT-LLVM-NEXT: Size: 0x8 # BADSECTION-OUT-LLVM-NEXT: Size: 0x8
# BADSECTION-OUT-LLVM-NEXT: } # BADSECTION-OUT-LLVM-NEXT: }
# BADSECTION-OUT-LLVM-NEXT: warning: '[[FILE]]': unable to get the target of relocation with index 2 in SHT_RELA section with index 3: unable to access section [index 4] data at 0x1880: offset goes past the end of file # BADSECTION-OUT-LLVM-NEXT: warning: '[[FILE]]': unable to get the target of relocation with index 2 in SHT_RELA section with index 3: unable to access section [index 4] data at 0x18a0: offset goes past the end of file
# BADSECTION-OUT-LLVM-NEXT: warning: '[[FILE]]': could not identify function symbol for stack size entry
# BADSECTION-OUT-LLVM-NEXT: Entry { # BADSECTION-OUT-LLVM-NEXT: Entry {
# BADSECTION-OUT-LLVM-NEXT: Function: ? # BADSECTION-OUT-LLVM-NEXT: Function: ?
# BADSECTION-OUT-LLVM-NEXT: Size: 0x16 # BADSECTION-OUT-LLVM-NEXT: Size: 0x16
# BADSECTION-OUT-LLVM-NEXT: } # BADSECTION-OUT-LLVM-NEXT: }
# BADSECTION-OUT-LLVM-NEXT: warning: '[[FILE]]': unable to get the target of relocation with index 3 in SHT_RELA section with index 3: unable to access section [index 4] data at 0x18a0: offset goes past the end of file
# BADSECTION-OUT-LLVM-NEXT: Entry {
# BADSECTION-OUT-LLVM-NEXT: Function: ?
# BADSECTION-OUT-LLVM-NEXT: Size: 0x24
# BADSECTION-OUT-LLVM-NEXT: }
# BADSECTION-OUT-LLVM-NEXT: ] # BADSECTION-OUT-LLVM-NEXT: ]
# RUN: llvm-readelf --stack-sizes --demangle %t07 2>&1 | FileCheck %s --check-prefix=BADSECTION-DEMANGLE-ERR -DFILE=%t07 # RUN: llvm-readelf --stack-sizes --demangle %t07 2>&1 | FileCheck %s --check-prefix=BADSECTION-DEMANGLE-ERR -DFILE=%t07
@ -444,6 +535,7 @@ Sections:
Entries: Entries:
- Size: 0x8 - Size: 0x8
- Size: 0x16 - Size: 0x16
- Size: 0x24
- Name: .rela.stack_sizes - Name: .rela.stack_sizes
Type: SHT_RELA Type: SHT_RELA
Info: .stack_sizes Info: .stack_sizes
@ -455,6 +547,10 @@ Sections:
## An invalid symbol index. ## An invalid symbol index.
Symbol: 0xff Symbol: 0xff
Type: R_X86_64_64 Type: R_X86_64_64
## One more invalid symbol index with the same symbol value (0xff).
- Offset: 0x12
Symbol: 0xff
Type: R_X86_64_64
Symbols: Symbols:
- Name: _Z3foof - Name: _Z3foof
## An invalid section index. ## An invalid section index.
@ -578,7 +674,7 @@ Sections:
# NONFUNCTIONSYM-LLVM-NEXT: } # NONFUNCTIONSYM-LLVM-NEXT: }
# NONFUNCTIONSYM-LLVM-NEXT: ] # NONFUNCTIONSYM-LLVM-NEXT: ]
# NONFUNCTIONSYM-ERR: warning: '[[FILE]]': could not identify function symbol for stack size entry # NONFUNCTIONSYM-ERR: warning: '[[FILE]]': could not identify function symbol for stack size entry in SHT_PROGBITS section with index 2
--- !ELF --- !ELF
FileHeader: FileHeader:

View File

@ -5798,53 +5798,64 @@ template <class ELFT> void GNUStyle<ELFT>::printDependentLibs() {
PrintSection(); PrintSection();
} }
// Used for printing symbol names in places where possible errors can be
// ignored.
static std::string getSymbolName(const ELFSymbolRef &Sym) {
Expected<StringRef> NameOrErr = Sym.getName();
if (NameOrErr)
return maybeDemangle(*NameOrErr);
consumeError(NameOrErr.takeError());
return "<?>";
}
template <class ELFT> template <class ELFT>
void DumpStyle<ELFT>::printFunctionStackSize( void DumpStyle<ELFT>::printFunctionStackSize(
uint64_t SymValue, Optional<const Elf_Shdr *> FunctionSec, uint64_t SymValue, Optional<const Elf_Shdr *> FunctionSec,
const Elf_Shdr &StackSizeSec, DataExtractor Data, uint64_t *Offset) { const Elf_Shdr &StackSizeSec, DataExtractor Data, uint64_t *Offset) {
// This function ignores potentially erroneous input, unless it is directly uint32_t FuncSymIndex = 0;
// related to stack size reporting. if (const Elf_Shdr *SymTab = this->dumper().getDotSymtabSec()) {
SymbolRef FuncSym; if (Expected<Elf_Sym_Range> SymsOrError = Obj.symbols(SymTab)) {
for (const ELFSymbolRef &Symbol : ElfObj.symbols()) { uint32_t Index = (uint32_t)-1;
Expected<uint64_t> SymAddrOrErr = Symbol.getAddress(); for (const Elf_Sym &Sym : *SymsOrError) {
if (!SymAddrOrErr) { ++Index;
consumeError(SymAddrOrErr.takeError());
continue; if (Sym.st_shndx == ELF::SHN_UNDEF || Sym.getType() != ELF::STT_FUNC)
} continue;
if (Expected<uint32_t> SymFlags = Symbol.getFlags()) {
if (*SymFlags & SymbolRef::SF_Undefined) if (Expected<uint64_t> SymAddrOrErr =
continue; ElfObj.toSymbolRef(SymTab, Index).getAddress()) {
} else if (SymValue != *SymAddrOrErr)
consumeError(SymFlags.takeError()); continue;
if (Symbol.getELFType() == ELF::STT_FUNC && *SymAddrOrErr == SymValue) { } else {
// Check if the symbol is in the right section. FunctionSec == None means std::string Name = this->dumper().getStaticSymbolName(Index);
// "any section". reportUniqueWarning("unable to get address of symbol '" + Name +
if (!FunctionSec || "': " + toString(SymAddrOrErr.takeError()));
ElfObj.toSectionRef(*FunctionSec).containsSymbol(Symbol)) { break;
FuncSym = Symbol; }
// Check if the symbol is in the right section. FunctionSec == None
// means "any section".
if (FunctionSec) {
if (Expected<const Elf_Shdr *> SecOrErr =
Obj.getSection(Sym, SymTab, this->dumper().getShndxTable())) {
if (*FunctionSec != *SecOrErr)
continue;
} else {
std::string Name = this->dumper().getStaticSymbolName(Index);
// Note: it is impossible to trigger this error currently, it is
// untested.
reportUniqueWarning("unable to get section of symbol '" + Name +
"': " + toString(SecOrErr.takeError()));
break;
}
}
FuncSymIndex = Index;
break; break;
} }
} else {
reportUniqueWarning("unable to read the symbol table: " +
toString(SymsOrError.takeError()));
} }
} }
std::string FuncName = "?"; std::string FuncName = "?";
// A valid SymbolRef has a non-null object file pointer. if (!FuncSymIndex)
if (FuncSym.BasicSymbolRef::getObject()) reportUniqueWarning(
FuncName = getSymbolName(FuncSym); "could not identify function symbol for stack size entry in " +
describe(Obj, StackSizeSec));
else else
reportWarning( FuncName = this->dumper().getStaticSymbolName(FuncSymIndex);
createError("could not identify function symbol for stack size entry"),
FileName);
// Extract the size. The expectation is that Offset is pointing to the right // Extract the size. The expectation is that Offset is pointing to the right
// place, i.e. past the function address. // place, i.e. past the function address.
@ -5853,13 +5864,10 @@ void DumpStyle<ELFT>::printFunctionStackSize(
// 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) {
reportWarning(createStringError(object_error::parse_failed, reportUniqueWarning("could not extract a valid stack size from " +
"could not extract a valid stack size in " + describe(Obj, StackSizeSec));
describe(Obj, StackSizeSec)),
FileName);
return; return;
} }
printStackSizeEntry(StackSize, FuncName); printStackSizeEntry(StackSize, FuncName);
} }