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

Function ScanForFunctions

pcsx2/DebugTools/MIPSAnalyst.cpp:178–365  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

176 }
177
178 void ScanForFunctions(ccc::SymbolDatabase& database, MemoryInterface& reader, u32 startAddr, u32 endAddr, bool generateHashes) {
179 std::vector<MIPSAnalyst::AnalyzedFunction> functions;
180 AnalyzedFunction currentFunction = {startAddr};
181
182 u32 furthestBranch = 0;
183 bool looking = false;
184 bool end = false;
185 bool isStraightLeaf = true;
186 bool suspectedNoReturn = false;
187
188 u32 addr;
189 for (addr = startAddr; addr < endAddr; addr += 4) {
190 // Use pre-existing symbol map info if available. May be more reliable.
191 ccc::FunctionHandle existing_symbol_handle = database.functions.first_handle_from_starting_address(addr);
192 const ccc::Function* existing_symbol = database.functions.symbol_from_handle(existing_symbol_handle);
193
194 if (existing_symbol && existing_symbol->address().valid() && existing_symbol->size() > 0) {
195 addr = existing_symbol->address().value + existing_symbol->size() - 4;
196 currentFunction.start = addr + 4;
197 furthestBranch = 0;
198 looking = false;
199 end = false;
200 continue;
201 }
202
203 u32 op = reader.Read32(addr);
204
205 u32 target = GetBranchTargetNoRA(addr, reader);
206 if (target != INVALIDTARGET) {
207 isStraightLeaf = false;
208 if (target > furthestBranch) {
209 furthestBranch = target;
210 }
211
212 // beq $zero, $zero, xyz
213 if ((op >> 16) == 0x1000)
214 {
215 // If it's backwards, and there's no other branch passing it, treat as noreturn
216 if(target < addr && furthestBranch < addr)
217 {
218 end = suspectedNoReturn = true;
219 }
220 }
221 } else if ((op & 0xFC000000) == 0x08000000) {
222 u32 sureTarget = GetJumpTarget(addr, reader);
223 // Check for a tail call. Might not even have a jr ra.
224 if (sureTarget != INVALIDTARGET && sureTarget < currentFunction.start) {
225 if (furthestBranch > addr) {
226 looking = true;
227 addr += 4;
228 } else {
229 end = true;
230 }
231 } else if (sureTarget != INVALIDTARGET && sureTarget > addr && sureTarget > furthestBranch) {
232 // A jump later. Probably tail, but let's check if it jumps back.
233 u32 knownEnd = furthestBranch == 0 ? addr : furthestBranch;
234 u32 jumpback = ScanAheadForJumpback(sureTarget, currentFunction.start, knownEnd, reader);
235 if (jumpback != INVALIDTARGET && jumpback > addr && jumpback > knownEnd) {

Callers 2

AnalyseElfMethod · 0.85
ScanForFunctionsMethod · 0.85

Calls 15

GetBranchTargetNoRAFunction · 0.85
GetJumpTargetFunction · 0.85
ScanAheadForJumpbackFunction · 0.85
GetSureBranchTargetFunction · 0.85
StdStringFromFormatFunction · 0.85
symbol_from_handleMethod · 0.80
addressMethod · 0.80
get_symbol_sourceMethod · 0.80
successMethod · 0.80
create_symbolMethod · 0.80

Tested by

no test coverage detected