예제 #1
0
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;
}
예제 #2
0
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;
  }
}