| 187 | } |
| 188 | |
| 189 | std::vector<StackFrame> Walk(DebugInterface* cpu, u32 pc, u32 ra, u32 sp, u32 threadEntry) |
| 190 | { |
| 191 | std::vector<StackFrame> frames; |
| 192 | StackFrame current; |
| 193 | current.pc = pc; |
| 194 | current.sp = sp; |
| 195 | current.entry = INVALIDTARGET; |
| 196 | current.stackSize = -1; |
| 197 | |
| 198 | u32 prevEntry = INVALIDTARGET; |
| 199 | while (pc != threadEntry) |
| 200 | { |
| 201 | u32 possibleEntry = GuessEntry(cpu, current.pc); |
| 202 | if (DetermineFrameInfo(cpu, current, possibleEntry, threadEntry, ra)) |
| 203 | { |
| 204 | frames.push_back(current); |
| 205 | if (current.entry == threadEntry || GuessEntry(cpu, current.entry) == threadEntry) |
| 206 | { |
| 207 | break; |
| 208 | } |
| 209 | if (current.entry == prevEntry || frames.size() >= MAX_DEPTH) |
| 210 | { |
| 211 | // Recursion, means we're screwed. Let's just give up. |
| 212 | break; |
| 213 | } |
| 214 | prevEntry = current.entry; |
| 215 | |
| 216 | current.pc = ra; |
| 217 | current.sp += current.stackSize; |
| 218 | ra = INVALIDTARGET; |
| 219 | current.entry = INVALIDTARGET; |
| 220 | current.stackSize = -1; |
| 221 | } |
| 222 | else |
| 223 | { |
| 224 | // Well, we got as far as we could. |
| 225 | current.entry = possibleEntry; |
| 226 | current.stackSize = 0; |
| 227 | frames.push_back(current); |
| 228 | break; |
| 229 | } |
| 230 | } |
| 231 | |
| 232 | return frames; |
| 233 | } |
| 234 | }; // namespace MipsStackWalk |
no test coverage detected