Adding a simple heuristic to find leaf thunk functions.
This commit is contained in:
parent
1640acaf8a
commit
f94256aaaf
|
@ -272,6 +272,7 @@ int SymbolDatabase::AnalyzeFunction(FunctionSymbol* fn) {
|
||||||
FunctionBlock* block = NULL;
|
FunctionBlock* block = NULL;
|
||||||
uint32_t furthest_target = fn->start_address;
|
uint32_t furthest_target = fn->start_address;
|
||||||
uint32_t addr = fn->start_address;
|
uint32_t addr = fn->start_address;
|
||||||
|
bool starts_with_mfspr_lr = false;
|
||||||
while (true) {
|
while (true) {
|
||||||
i.code = XEGETUINT32BE(p + addr);
|
i.code = XEGETUINT32BE(p + addr);
|
||||||
i.type = ppc::GetInstrType(i.code);
|
i.type = ppc::GetInstrType(i.code);
|
||||||
|
@ -284,6 +285,16 @@ int SymbolDatabase::AnalyzeFunction(FunctionSymbol* fn) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if the function starts with a mfspr lr, as that's a good indication
|
||||||
|
// of whether or not this is a normal function with a prolog/epilog.
|
||||||
|
// Some valid leaf functions won't have this, but most will.
|
||||||
|
if (addr == fn->start_address &&
|
||||||
|
i.type &&
|
||||||
|
i.type->opcode == 0x7C0002A6 &&
|
||||||
|
(((i.XFX.spr & 0x1F) << 5) | ((i.XFX.spr >> 5) & 0x1F)) == 8) {
|
||||||
|
starts_with_mfspr_lr = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Create a new basic block, if needed.
|
// Create a new basic block, if needed.
|
||||||
if (!block) {
|
if (!block) {
|
||||||
block = new FunctionBlock();
|
block = new FunctionBlock();
|
||||||
|
@ -357,6 +368,19 @@ int SymbolDatabase::AnalyzeFunction(FunctionSymbol* fn) {
|
||||||
ends_fn = true;
|
ends_fn = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Heuristic: if there's an unconditional branch in the first block of
|
||||||
|
// the function it's likely a thunk.
|
||||||
|
// Ex:
|
||||||
|
// li r3, 0
|
||||||
|
// b KeBugCheck
|
||||||
|
// This check may hit on functions that jump over data code, so only
|
||||||
|
// trigger this check in leaf functions (no mfspr lr/prolog).
|
||||||
|
if (!starts_with_mfspr_lr &&
|
||||||
|
fn->blocks.size() == 1) {
|
||||||
|
XELOGSDB("simple leaf thunk detected, ending");
|
||||||
|
ends_fn = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!ends_fn) {
|
if (!ends_fn) {
|
||||||
furthest_target = MAX(furthest_target, target);
|
furthest_target = MAX(furthest_target, target);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue