MCPcopy Create free account
hub / github.com/PCSX2/pcsx2 / ScanAheadForJumpback

Function ScanAheadForJumpback

pcsx2/DebugTools/MIPSAnalyst.cpp:118–176  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

116 }
117
118 static u32 ScanAheadForJumpback(u32 fromAddr, u32 knownStart, u32 knownEnd, MemoryInterface& reader) {
119 static const u32 MAX_AHEAD_SCAN = 0x1000;
120 // Maybe a bit high... just to make sure we don't get confused by recursive tail recursion.
121 static const u32 MAX_FUNC_SIZE = 0x20000;
122
123 if (fromAddr > knownEnd + MAX_FUNC_SIZE) {
124 return INVALIDTARGET;
125 }
126
127 // Code might jump halfway up to before fromAddr, but after knownEnd.
128 // In that area, there could be another jump up to the valid range.
129 // So we track that for a second scan.
130 u32 closestJumpbackAddr = INVALIDTARGET;
131 u32 closestJumpbackTarget = fromAddr;
132
133 // We assume the furthest jumpback is within the func.
134 u32 furthestJumpbackAddr = INVALIDTARGET;
135
136 for (u32 ahead = fromAddr; ahead < fromAddr + MAX_AHEAD_SCAN; ahead += 4) {
137 u32 aheadOp = reader.Read32(ahead);
138 u32 target = GetBranchTargetNoRA(ahead, reader);
139 if (target == INVALIDTARGET && ((aheadOp & 0xFC000000) == 0x08000000)) {
140 target = GetJumpTarget(ahead, reader);
141 }
142
143 if (target != INVALIDTARGET) {
144 // Only if it comes back up to known code within this func.
145 if (target >= knownStart && target <= knownEnd) {
146 furthestJumpbackAddr = ahead;
147 }
148 // But if it jumps above fromAddr, we should scan that area too...
149 if (target < closestJumpbackTarget && target < fromAddr && target > knownEnd) {
150 closestJumpbackAddr = ahead;
151 closestJumpbackTarget = target;
152 }
153 }
154 if (aheadOp == MIPS_MAKE_JR_RA()) {
155 break;
156 }
157 }
158
159 if (closestJumpbackAddr != INVALIDTARGET && furthestJumpbackAddr == INVALIDTARGET) {
160 for (u32 behind = closestJumpbackTarget; behind < fromAddr; behind += 4) {
161 u32 behindOp = reader.Read32(behind);
162 u32 target = GetBranchTargetNoRA(behind, reader);
163 if (target == INVALIDTARGET && ((behindOp & 0xFC000000) == 0x08000000)) {
164 target = GetJumpTarget(behind, reader);
165 }
166
167 if (target != INVALIDTARGET) {
168 if (target >= knownStart && target <= knownEnd) {
169 furthestJumpbackAddr = closestJumpbackAddr;
170 }
171 }
172 }
173 }
174
175 return furthestJumpbackAddr;

Callers 1

ScanForFunctionsFunction · 0.85

Calls 3

GetBranchTargetNoRAFunction · 0.85
GetJumpTargetFunction · 0.85
Read32Method · 0.45

Tested by

no test coverage detected