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);
}
ELFSymbolRef toSymbolRef(const Elf_Shdr *SymTable, unsigned SymbolNum) const {
return ELFSymbolRef({toDRI(SymTable, SymbolNum), this});
}
bool IsContentValid() const { return ContentValid; }
private:

View File

@ -74,10 +74,14 @@ Sections:
- Offset: 0
Symbol: separate_text_section_baz
Type: R_X86_64_64
- Name: .symtab
Type: SHT_SYMTAB
ShOffset: [[SYMTABOFFSET=<none>]]
Symbols:
- Name: separate_text_section_baz
Section: .text.baz
Section: [[SEC1=.text.baz]]
Type: STT_FUNC
Index: [[SEC1INDEX=<none>]]
- Name: .text
Section: .text
Type: STT_SECTION
@ -91,6 +95,86 @@ Symbols:
Type: STT_FUNC
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)
## object file. This also shows that the sh_link field is ignored in this situation
## without warning.
@ -361,8 +445,8 @@ Symbols:
# 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
# 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 in SHT_PROGBITS section with index 3
# 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 from SHT_PROGBITS section with index 3
--- !ELF
FileHeader:
@ -402,25 +486,32 @@ Symbols:
# BADSECTION-OUT-GNU: Stack Sizes:
# 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]]': 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: 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]]': could not identify function symbol for stack size entry
# BADSECTION-OUT-GNU-NEXT: 22 ?
# 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: 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-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: Function: ?
# BADSECTION-OUT-LLVM-NEXT: Size: 0x8
# 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]]': could not identify function symbol for stack size entry
# 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: Entry {
# BADSECTION-OUT-LLVM-NEXT: Function: ?
# BADSECTION-OUT-LLVM-NEXT: Size: 0x16
# 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: ]
# RUN: llvm-readelf --stack-sizes --demangle %t07 2>&1 | FileCheck %s --check-prefix=BADSECTION-DEMANGLE-ERR -DFILE=%t07
@ -444,6 +535,7 @@ Sections:
Entries:
- Size: 0x8
- Size: 0x16
- Size: 0x24
- Name: .rela.stack_sizes
Type: SHT_RELA
Info: .stack_sizes
@ -455,6 +547,10 @@ Sections:
## An invalid symbol index.
Symbol: 0xff
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:
- Name: _Z3foof
## An invalid section index.
@ -578,7 +674,7 @@ Sections:
# 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
FileHeader:

View File

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