bool isNopInsn(Instruction::Ptr insn) { // TODO: add LEA no-ops if(insn->getOperation().getID() == e_nop) return true; if(insn->getOperation().getID() == e_lea) { std::set<Expression::Ptr> memReadAddr; insn->getMemoryReadOperands(memReadAddr); std::set<RegisterAST::Ptr> writtenRegs; insn->getWriteSet(writtenRegs); if(memReadAddr.size() == 1 && writtenRegs.size() == 1) { if(**(memReadAddr.begin()) == **(writtenRegs.begin())) { return true; } } // Check for zero displacement nopVisitor visitor; // We need to get the src operand insn->getOperand(1).getValue()->apply(&visitor); if (visitor.isNop) return true; } return false; }
bool IA_x86Details::computeTableBounds(Instruction::Ptr maxSwitchInsn, Instruction::Ptr branchInsn, Instruction::Ptr tableInsn, bool foundJCCAlongTaken, unsigned& tableSize, unsigned& tableStride) { assert(maxSwitchInsn && branchInsn); Result compareBound = maxSwitchInsn->getOperand(1).getValue()->eval(); if(!compareBound.defined) return false; tableSize = compareBound.convert<unsigned>(); // Sanity check the bounds; 32k tables would be an oddity, and larger is almost certainly // a misparse static const unsigned int maxTableSize = 32768; if(tableSize > maxTableSize) { parsing_printf("\tmaxSwitch of %d above %d, BAILING OUT\n", tableSize, maxTableSize); return false; } if(foundJCCAlongTaken) { if(branchInsn->getOperation().getID() == e_jbe || branchInsn->getOperation().getID() == e_jle) { tableSize++; } } else { if(branchInsn->getOperation().getID() == e_jnbe || branchInsn->getOperation().getID() == e_jnle) { tableSize++; } } parsing_printf("\tmaxSwitch set to %d\n", tableSize); tableStride = currentBlock->_isrc->getAddressWidth(); std::set<Expression::Ptr> tableInsnReadAddr; tableInsn->getMemoryReadOperands(tableInsnReadAddr); if(tableStride == 8) { static Immediate::Ptr four(new Immediate(Result(u8, 4))); static BinaryFunction::funcT::Ptr multiplier(new BinaryFunction::multResult()); static Expression::Ptr dummy(new DummyExpr()); static BinaryFunction::Ptr scaleCheck(new BinaryFunction(four, dummy, u64, multiplier)); for(std::set<Expression::Ptr>::const_iterator curExpr = tableInsnReadAddr.begin(); curExpr != tableInsnReadAddr.end(); ++curExpr) { if((*curExpr)->isUsed(scaleCheck)) { tableSize = tableSize >> 1; parsing_printf("\tmaxSwitch revised to %d\n",tableSize); } } }