bool IA_IAPI::savesFP() const { std::vector<Instruction::Ptr> insns; insns.push_back(curInsn()); #if defined(os_windows) // Windows functions can start with a noop... InstructionDecoder tmp(dec); insns.push_back(tmp.decode()); #endif for (unsigned i = 0; i < insns.size(); ++i) { InstructionAPI::Instruction::Ptr ci = insns[i]; if(ci->getOperation().getID() == e_push) { if (ci->isRead(framePtr[_isrc->getArch()])) { return true; } else return false; } } return false; }
bool IA_powerDetails::scanForAdjustOrBase(IA_IAPI::allInsns_t::const_iterator start, IA_IAPI::allInsns_t::const_iterator end, RegisterAST::Ptr &jumpAddrReg) { std::set<RegisterAST::Ptr> scratchRegs; std::set<RegisterAST::Ptr> loadRegs; loadRegs.insert(jumpAddrReg); for (; start != end; --start) { InstructionAPI::Instruction::Ptr insn = start->second; parsing_printf("\t\t Examining 0x%lx / %s\n", start->first, start->second->format().c_str()); if ((insn->getOperation().getID() == power_op_ld || insn->getOperation().getID() == power_op_ldx) && insn->isWritten(jumpAddrReg)) { scratchRegs.clear(); insn->getReadSet(scratchRegs); loadRegs.insert(scratchRegs.begin(), scratchRegs.end()); parsing_printf("Found a load; now have %d load regs\n", loadRegs.size()); } else if(insn->getOperation().getID() == power_op_addi && !foundAdjustEntry) { parsing_printf("Found add immediate (%d load regs)...\n", loadRegs.size()); scratchRegs.clear(); insn->getWriteSet(scratchRegs); bool found = false; // This is apparently broken for (std::set<RegisterAST::Ptr>::iterator iter = loadRegs.begin(); iter != loadRegs.end(); ++iter) { RegisterAST *tmp = (*iter).get(); RegisterAST *cmp = (*(scratchRegs.begin())).get(); if (*tmp == *cmp) { found = true; break; } } if (!found) continue; parsing_printf("... that adds to a load reg\n"); foundAdjustEntry = true; toc_visitor->clear(); parsing_printf("... with operand %s\n", insn->getOperand(1).format(insn->getArch(), start->first).c_str()); insn->getOperand(1).getValue()->apply(toc_visitor.get()); adjustEntry = toc_visitor->result; if (!adjustEntry) insn->getOperand(2).getValue()->apply(toc_visitor.get()); adjustEntry = toc_visitor->result; } else if((insn->getOperation().getID() == power_op_lwz || insn->getOperation().getID() == power_op_ld) && insn->isRead(toc_reg) && insn->isWritten(jumpAddrReg)) { parsing_printf("\t found TOC load at %s\n", insn->format().c_str()); toc_visitor->clear(); insn->getOperand(1).getValue()->apply(toc_visitor.get()); tableStartAddress = toc_visitor->result; break; } } return true; }