mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-22 02:39:05 +02:00
Stack walk: Report a function's symbol start as its entry, not its prologue
The scan for the prologue took the addiu sp as the entry, which is past the start when the function does something first (a lui, a move). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
2cfbbc001d
commit
024bed6065
2 files changed
+27
-1
No files matched your search
@@ -145,7 +145,10 @@ namespace MIPSStackWalk {
|
||||
continue;
|
||||
}
|
||||
|
||||
frame.entry = pc;
|
||||
// The prologue often isn't the first instruction (a lui or move can come first), so
|
||||
// the function's symbol, if it has one, gives the real entry.
|
||||
const u32 symbolEntry = GuessEntry(pc);
|
||||
frame.entry = symbolEntry != INVALIDTARGET ? symbolEntry : pc;
|
||||
frame.stackSize = -_IMM16;
|
||||
if (ra_offset != -1 && Memory::IsValid4AlignedAddress(frame.sp + ra_offset)) {
|
||||
ra = Memory::ReadUnchecked_U32(frame.sp + ra_offset);
|
||||
|
||||
@@ -2501,6 +2501,29 @@ static bool CheckStackWalk() {
|
||||
EXPECT_EQ_HEX(frames[1].pc, caller + 0x10);
|
||||
EXPECT_EQ_HEX(frames[1].entry, caller);
|
||||
EXPECT_EQ_INT(frames[1].stackSize, 16);
|
||||
|
||||
// With a symbol, the entry is where it starts, even when the prologue isn't first.
|
||||
const u32 func = 0x08805000;
|
||||
const u32 funcCode[] = {
|
||||
0x3C080000, // func: lui t0, 0
|
||||
0x27BDFFF0, // addiu sp, sp, -16
|
||||
0xAFBF000C, // sw ra, 12(sp)
|
||||
0x00000000, // nop
|
||||
};
|
||||
for (size_t i = 0; i < ARRAY_SIZE(funcCode); i++) {
|
||||
Memory::WriteUnchecked_U32(funcCode[i], func + (u32)i * 4);
|
||||
}
|
||||
Memory::WriteUnchecked_U32(caller + 0x10, sp + 12);
|
||||
symbolMap.AddFunction("func", func, sizeof(funcCode));
|
||||
symbolMap.SortSymbols();
|
||||
g_symbolMap = &symbolMap;
|
||||
frames = MIPSStackWalk::Walk(func + 0xC, caller + 0x10, sp, caller, 0x09F00000);
|
||||
g_symbolMap = nullptr;
|
||||
|
||||
EXPECT_EQ_INT((int)frames.size(), 2);
|
||||
EXPECT_EQ_HEX(frames[0].entry, func);
|
||||
EXPECT_EQ_INT(frames[0].stackSize, 16);
|
||||
EXPECT_EQ_HEX(frames[1].pc, caller + 0x10);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user