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; }
void AbsRegionConverter::convertAll(InstructionAPI::Instruction::Ptr insn, Address addr, ParseAPI::Function *func, ParseAPI::Block *block, std::vector<AbsRegion> &used, std::vector<AbsRegion> &defined) { if (!usedCache(addr, func, used)) { std::set<RegisterAST::Ptr> regsRead; insn->getReadSet(regsRead); for (std::set<RegisterAST::Ptr>::const_iterator i = regsRead.begin(); i != regsRead.end(); ++i) { used.push_back(AbsRegionConverter::convert(*i)); } if (insn->readsMemory()) { std::set<Expression::Ptr> memReads; insn->getMemoryReadOperands(memReads); for (std::set<Expression::Ptr>::const_iterator r = memReads.begin(); r != memReads.end(); ++r) { used.push_back(AbsRegionConverter::convert(*r, addr, func, block)); } } } if (!definedCache(addr, func, defined)) { // Defined time std::set<RegisterAST::Ptr> regsWritten; insn->getWriteSet(regsWritten); for (std::set<RegisterAST::Ptr>::const_iterator i = regsWritten.begin(); i != regsWritten.end(); ++i) { defined.push_back(AbsRegionConverter::convert(*i)); } // special case for repeat-prefixed instructions on x86 // may disappear if Dyninst's representation of these instructions changes if (insn->getArch() == Arch_x86) { prefixEntryID insnPrefix = insn->getOperation().getPrefixID(); if ( (prefix_rep == insnPrefix) || (prefix_repnz == insnPrefix) ) { defined.push_back(AbsRegionConverter::convert(RegisterAST::Ptr( new RegisterAST(MachRegister::getPC(Arch_x86))))); } } if (insn->writesMemory()) { std::set<Expression::Ptr> memWrites; insn->getMemoryWriteOperands(memWrites); for (std::set<Expression::Ptr>::const_iterator r = memWrites.begin(); r != memWrites.end(); ++r) { defined.push_back(AbsRegionConverter::convert(*r, addr, func, block)); } } } if (cacheEnabled_) { used_cache_[func][addr] = used; defined_cache_[func][addr] = defined; } }