Merge pull request #5386 from sepalani/ppc-analyst-target

PPCAnalyst: Fix annoyances
This commit is contained in:
Anthony
2017-05-13 09:03:34 -07:00
committed by GitHub

View File

@ -53,7 +53,15 @@ static u32 EvaluateBranchTarget(UGeckoInstruction instr, u32 pc)
{ {
switch (instr.OPCD) switch (instr.OPCD)
{ {
case 18: // branch instruction case 16: // bcx - Branch Conditional instructions
{
u32 target = SignExt16(instr.BD << 2);
if (!instr.AA)
target += pc;
return target;
}
case 18: // bx - Branch instructions
{ {
u32 target = SignExt26(instr.LI << 2); u32 target = SignExt26(instr.LI << 2);
if (!instr.AA) if (!instr.AA)
@ -83,11 +91,10 @@ bool AnalyzeFunction(u32 startAddr, Symbol& func, int max_size)
func.callers.clear(); func.callers.clear();
func.size = 0; func.size = 0;
func.flags = FFLAG_LEAF; func.flags = FFLAG_LEAF;
u32 addr = startAddr;
u32 farthestInternalBranchTarget = startAddr; u32 farthestInternalBranchTarget = startAddr;
int numInternalBranches = 0; int numInternalBranches = 0;
while (true) for (u32 addr = startAddr; true; addr += 4)
{ {
func.size += 4; func.size += 4;
if (func.size >= CODEBUFFER_SIZE * 4 || !PowerPC::HostIsRAMAddress(addr)) // weird if (func.size >= CODEBUFFER_SIZE * 4 || !PowerPC::HostIsRAMAddress(addr)) // weird
@ -97,7 +104,8 @@ bool AnalyzeFunction(u32 startAddr, Symbol& func, int max_size)
{ {
func.address = startAddr; func.address = startAddr;
func.analyzed = true; func.analyzed = true;
func.hash = HashSignatureDB::ComputeCodeChecksum(startAddr, addr); func.size -= 4;
func.hash = HashSignatureDB::ComputeCodeChecksum(startAddr, addr - 4);
if (numInternalBranches == 0) if (numInternalBranches == 0)
func.flags |= FFLAG_STRAIGHT; func.flags |= FFLAG_STRAIGHT;
return true; return true;
@ -110,22 +118,19 @@ bool AnalyzeFunction(u32 startAddr, Symbol& func, int max_size)
// 4e800021 is blrl, not the end of a function // 4e800021 is blrl, not the end of a function
if (instr.hex == 0x4e800020 || instr.hex == 0x4C000064) if (instr.hex == 0x4e800020 || instr.hex == 0x4C000064)
{ {
// Not this one, continue..
if (farthestInternalBranchTarget > addr) if (farthestInternalBranchTarget > addr)
{ continue;
// bah, not this one, continue..
} // A final blr!
else // We're done! Looks like we have a neat valid function. Perfect.
{ // Let's calc the checksum and get outta here
// a final blr! func.address = startAddr;
// We're done! Looks like we have a neat valid function. Perfect. func.analyzed = true;
// Let's calc the checksum and get outta here func.hash = HashSignatureDB::ComputeCodeChecksum(startAddr, addr);
func.address = startAddr; if (numInternalBranches == 0)
func.analyzed = true; func.flags |= FFLAG_STRAIGHT;
func.hash = HashSignatureDB::ComputeCodeChecksum(startAddr, addr); return true;
if (numInternalBranches == 0)
func.flags |= FFLAG_STRAIGHT;
return true;
}
} }
/* /*
else if ((instr.hex & 0xFC000000) == (0x4b000000 & 0xFC000000) && !instr.LK) else if ((instr.hex & 0xFC000000) == (0x4b000000 & 0xFC000000) && !instr.LK)
@ -155,36 +160,32 @@ bool AnalyzeFunction(u32 startAddr, Symbol& func, int max_size)
} }
else else
{ {
if (instr.OPCD == 16) u32 target = EvaluateBranchTarget(instr, addr);
if (target == INVALID_BRANCH_TARGET)
continue;
const bool is_external = target < startAddr || (max_size && target >= startAddr + max_size);
if (instr.LK || is_external)
{ {
u32 target = SignExt16(instr.BD << 2); // Found a function call
func.calls.emplace_back(target, addr);
if (!instr.AA) func.flags &= ~FFLAG_LEAF;
target += addr; }
else if (instr.OPCD == 16)
if (target > farthestInternalBranchTarget && !instr.LK) {
// Found a conditional branch
if (target > farthestInternalBranchTarget)
{ {
farthestInternalBranchTarget = target; farthestInternalBranchTarget = target;
} }
numInternalBranches++; numInternalBranches++;
} }
else
{
u32 target = EvaluateBranchTarget(instr, addr);
if (target != INVALID_BRANCH_TARGET && instr.LK)
{
// we found a branch-n-link!
func.calls.emplace_back(target, addr);
func.flags &= ~FFLAG_LEAF;
}
}
} }
} }
else else
{ {
return false; return false;
} }
addr += 4;
} }
} }