| 97 | } |
| 98 | |
| 99 | bool ScanForEntry(DebugInterface* cpu, StackFrame& frame, u32 entry, u32& ra) |
| 100 | { |
| 101 | // Let's hope there are no > 1MB functions on the PSP, for the sake of humanity... |
| 102 | const u32 LONGEST_FUNCTION = 1024 * 1024; |
| 103 | // TODO: Check if found entry is in the same symbol? Might be wrong sometimes... |
| 104 | |
| 105 | int ra_offset = -1; |
| 106 | |
| 107 | // The instruction pointed to by pc hasn't been executed yet, |
| 108 | // so we don't want to consider it here |
| 109 | const u32 start = frame.pc - 4; |
| 110 | u32 stop = entry; |
| 111 | |
| 112 | if (entry == INVALIDTARGET) |
| 113 | { |
| 114 | stop = static_cast<u32>(std::max<s64>(0, (s64)start - LONGEST_FUNCTION)); |
| 115 | } |
| 116 | |
| 117 | for (u32 pc = start; cpu->isValidAddress(pc) && pc >= stop; pc -= 4) |
| 118 | { |
| 119 | u32 rawOp = cpu->Read32(pc); |
| 120 | const R5900::OPCODE& op = R5900::GetInstruction(rawOp); |
| 121 | |
| 122 | // Look for RA write to ram |
| 123 | if (IsSWInstr(op) && _RT == MIPS_REG_RA && _RS == MIPS_REG_SP) |
| 124 | { |
| 125 | ra_offset = _IMM16; |
| 126 | } |
| 127 | |
| 128 | // Look for previous function end |
| 129 | if (IsJRInstr(op) && _RS == MIPS_REG_RA) |
| 130 | { |
| 131 | // Found previous function end |
| 132 | // Since no stack setup was found assume this is a leaf |
| 133 | // with no stack usage |
| 134 | pc = pc + 8; |
| 135 | |
| 136 | frame.entry = pc; |
| 137 | frame.stackSize = 0; |
| 138 | |
| 139 | return true; |
| 140 | } |
| 141 | |
| 142 | // Look for the frame allocation stack pointer subtraction |
| 143 | if (IsAddImmInstr(op) && _RT == MIPS_REG_SP && _RS == MIPS_REG_SP) |
| 144 | { |
| 145 | // A positive imm either means alloca() or we went too far. |
| 146 | if (_IMM16 > 0) |
| 147 | { |
| 148 | // TODO: Maybe check for any alloca() signature and bail? |
| 149 | continue; |
| 150 | } |
| 151 | if (ScanForAllocaSignature(cpu, pc)) |
| 152 | { |
| 153 | continue; |
| 154 | } |
| 155 | |
| 156 | frame.entry = pc; |
no test coverage detected