void WriteFuncMissingStub(u32 stubAddr, u32 nid) { // Write a trap so we notice this func if it's called before resolving. Memory::Write_U32(MIPS_MAKE_JR_RA(), stubAddr); // jr ra Memory::Write_U32(GetSyscallOp(NULL, nid), stubAddr + 4); }
void ScanForFunctions(u32 startAddr, u32 endAddr /*, std::vector<u32> knownEntries*/) { Function currentFunction = {startAddr}; u32 furthestBranch = 0; bool looking = false; bool end = false; bool isStraightLeaf=true; u32 addr; for (addr = startAddr; addr<=endAddr; addr+=4) { int n = symbolMap.GetSymbolNum(addr,ST_FUNCTION); if (n != -1) { addr = symbolMap.GetSymbolAddr(n) + symbolMap.GetSymbolSize(n); continue; } u32 op = Memory::Read_Instruction(addr); u32 target = GetBranchTarget(addr); if (target != INVALIDTARGET) { isStraightLeaf = false; if (target > furthestBranch) { furthestBranch = target; } } if (op == MIPS_MAKE_JR_RA()) { if (furthestBranch >= addr) { looking = true; addr+=4; } else { end = true; } } if (looking) { if (addr >= furthestBranch) { u32 sureTarget = GetSureBranchTarget(addr); if (sureTarget != INVALIDTARGET && sureTarget < addr) { end = true; } sureTarget = GetJumpTarget(addr); if (sureTarget != INVALIDTARGET && sureTarget < addr && ((op&0xFC000000)==0x08000000)) { end = true; } //end = true; } } if (end) { currentFunction.end = addr + 4; currentFunction.isStraightLeaf = isStraightLeaf; functions.push_back(currentFunction); furthestBranch = 0; addr += 4; looking = false; end = false; isStraightLeaf=true; currentFunction.start = addr+4; } } currentFunction.end = addr + 4; functions.push_back(currentFunction); for (vector<Function>::iterator iter = functions.begin(); iter!=functions.end(); iter++) { (*iter).size = ((*iter).end-(*iter).start+4); char temp[256]; sprintf(temp,"z_un_%08x",(*iter).start); symbolMap.AddSymbol(std::string(temp).c_str(), (*iter).start,(*iter).end-(*iter).start+4,ST_FUNCTION); } HashFunctions(); }