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:
parent
4b64a9ef7d
commit
a9fdb4b116
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user