package janala.interpreters; import static janala.interpreters.ObjectValue.ADDRESS_UNKNOWN; import janala.Main; import janala.config.Config; import janala.instrument.Coverage; import janala.logger.ClassNames; import janala.logger.FieldInfo; import janala.logger.ObjectInfo; import janala.logger.inst.*; import janala.solvers.History; import janala.utils.MyLogger; import org.objectweb.asm.Type; import java.util.HashMap; import java.util.Map; import java.util.Stack; import java.util.logging.Level; import java.util.logging.Logger; public class ConcolicInterpreter implements IVisitor { private Stack<Frame> stack; public Stack<Frame> getStack() { return stack; } public void printCurrentStack() { System.out.println("Frame:"); System.out.println(currentFrame); } private Frame currentFrame; public Frame getCurrentFrame() { return currentFrame; } private ClassNames cnames; private Map<Integer, Value> objects; private History history; public History getHistory() { return history; } private Instruction next; private final Coverage coverage; private final StaticInvocation staticInv; private final Config config; private final static Logger logger = MyLogger.getLogger(ConcolicInterpreter.class.getName()); public ConcolicInterpreter(ClassNames cnames, Config config) { stack = new Stack<Frame>(); stack.add(currentFrame = new Frame(0)); this.cnames = cnames; objects = new HashMap<Integer, Value>(); history = History.readHistory(config.getSolver()); coverage = Coverage.get(); staticInv = new StaticInvocation(config); this.config = config; } // Used for testing with dependencies. public ConcolicInterpreter(ClassNames cnames, History history, Coverage coverage, Config config) { stack = new Stack<Frame>(); stack.add(currentFrame = new Frame(0)); this.cnames = cnames; objects = new HashMap<Integer, Value>(); this.history = history; // this.coverage = coverage; staticInv = new StaticInvocation(config); this.config = config; } private void checkAndSetException() { if (!(next instanceof SPECIAL) || ((SPECIAL) next).i != 0) { currentFrame.clear(); currentFrame.push(PlaceHolder.instance); } } private void checkAndSetBranch(IntValue cr) { cr.concrete = 0; // The false branch does not have the special instruction. if (next instanceof SPECIAL) { // See SnoopInstructionMethodAdapter, // 1 corresponds to the true branch. if (((SPECIAL) next).i == 1) { cr.concrete = 1; } } } private static SymbolicObject getSymbolicObject(final ObjectValue ref) { SymbolicObject sref; if (ref.symbolic != null) { sref = ref.symbolic; } else { sref = new SymbolicObject(); sref.addGuardedObjectValue(null, ref); } return sref; } private Value getArrayElementObject(int iid, final ObjectValue ref, final IntValue i1, final Value val) { if (i1.symbolic != null) { SymbolicObject tmp = new SymbolicObject(); SymbolicAndConstraint and1; final SymbolicObject sref = getSymbolicObject(ref); for (Pair<Constraint, ObjectValue> pair : sref.guards) { ObjectValue reference = pair.snd; for (int i = 0; i < reference.getFields().length; i++) { IntValue int1 = i1.IF_ICMPEQ(new IntValue(i)); Constraint c = int1.symbolic; if (int1.concrete == 0) { c = int1.symbolic.not(); } if (pair.fst != null) { and1 = new SymbolicAndConstraint(c); c = and1.AND(pair.fst); } tmp.addGuardedObjectValue(c, (ObjectValue) reference.getField(i)); } } return new ObjectValue((ObjectValue) val, tmp); } return val; } private Value getArrayElementInt(int iid, final ObjectValue ref, final IntValue i1, final Value val) { if (i1.symbolic != null) { SymbolicOrConstraint or1 = null; SymbolicAndConstraint and1; final SymbolicObject sref = getSymbolicObject(ref); IntValue sval = new IntValue(((IntValue) val).concrete); sval.MAKE_SYMBOLIC(history); for (Pair<Constraint, ObjectValue> pair : sref.guards) { ObjectValue reference = pair.snd; for (int i = 0; i < reference.getFields().length; i++) { // Check index IntValue int1 = i1.IF_ICMPEQ(new IntValue(i)); Constraint c = int1.symbolic; if (int1.concrete == 0) { c = int1.symbolic.not(); } and1 = new SymbolicAndConstraint(c); if (pair.fst != null) { and1 = and1.AND(pair.fst); } // Check the value of the element in the array. int1 = sval.IF_ICMPEQ((IntValue) reference.getField(i)); c = int1.symbolic; if (int1.concrete == 0) { c = int1.symbolic.not(); } and1 = and1.AND(c); if (or1 == null) { or1 = new SymbolicOrConstraint(and1); } else { or1 = or1.OR(and1); } } } history.checkAndSetBranch(true, or1, iid); history.setLastBranchDone(); return sval; } return val; } private Value getArrayElementLong(int iid, ObjectValue ref, IntValue i1, Value val) { if (i1.symbolic != null) { LongValue sval = new LongValue(((LongValue) val).getConcreteLong()); sval.MAKE_SYMBOLIC(history); SymbolicOrConstraint or1 = null; SymbolicAndConstraint and1; final SymbolicObject sref = getSymbolicObject(ref); for (Pair<Constraint, ObjectValue> pair : sref.guards) { ref = pair.snd; for (int i = 0; i < ref.getFields().length; i++) { IntValue int1 = i1.IF_ICMPEQ(new IntValue(i)); Constraint c = int1.symbolic; if (int1.concrete == 0) { c = int1.symbolic.not(); } and1 = new SymbolicAndConstraint(c); if (pair.fst != null) { and1 = and1.AND(pair.fst); } int1 = sval.LCMP((LongValue) ref.getField(i)); int1 = int1.IFEQ(); c = int1.symbolic; if (int1.concrete == 0) { c = int1.symbolic.not(); } and1 = and1.AND(c); if (or1 == null) { or1 = new SymbolicOrConstraint(and1); } else { or1 = or1.OR(and1); } } } history.checkAndSetBranch(true, or1, iid); history.setLastBranchDone(); val = sval; } return val; } public void endExecution() { if (history != null) { history.solveAndSave(); } Main.writeOldStates(); coverage.write(config.coverage); } public void visitAALOAD(AALOAD inst) { try { IntValue i1 = (IntValue) currentFrame.pop(); ObjectValue ref = (ObjectValue) currentFrame.pop(); Value val = ref.getField(i1.concrete); Value v = getArrayElementObject(inst.iid, ref, i1, val); currentFrame.push(v); } catch (Exception e) { e.printStackTrace(); } checkAndSetException(); } public void visitAASTORE(AASTORE inst) { try { Value value = currentFrame.pop(); IntValue i = (IntValue) currentFrame.pop(); ObjectValue ref = (ObjectValue) currentFrame.pop(); ref.setField(i.concrete, value); } catch (Exception e) { e.printStackTrace(); } checkAndSetException(); } public void visitACONST_NULL(ACONST_NULL inst) { currentFrame.push(ObjectValue.NULL); } public void visitALOAD(ALOAD inst) { currentFrame.push(currentFrame.getLocal(inst.var)); } public void visitANEWARRAY(ANEWARRAY inst) { try { IntValue i1 = (IntValue) currentFrame.pop(); ObjectValue tmp = new ObjectValue(i1.concrete); currentFrame.push(tmp); } catch (Exception e) { e.printStackTrace(); } } public void visitARETURN(ARETURN inst) { currentFrame.setRet(currentFrame.pop()); } public void visitARRAYLENGTH(ARRAYLENGTH inst) { try { ObjectValue ref = (ObjectValue) currentFrame.pop(); if (ref.getFields() == null) { currentFrame.push(PlaceHolder.instance); } else { currentFrame.push(new IntValue(ref.getFields().length)); } } catch (Exception e) { e.printStackTrace(); } checkAndSetException(); } public void visitASTORE(ASTORE inst) { currentFrame.setLocal(inst.var, currentFrame.pop()); } public void visitATHROW(ATHROW inst) { Value top = currentFrame.peek(); currentFrame.clear(); currentFrame.push(top); } public void visitBALOAD(BALOAD inst) { try { IntValue i1 = (IntValue) currentFrame.pop(); ObjectValue ref = (ObjectValue) currentFrame.pop(); Value val = ref.getField(i1.concrete); currentFrame.push(getArrayElementInt(inst.iid, ref, i1, val)); } catch (Exception e) { e.printStackTrace(); } checkAndSetException(); } public void visitBASTORE(BASTORE inst) { try { Value value = currentFrame.pop(); IntValue i = (IntValue) currentFrame.pop(); ObjectValue ref = (ObjectValue) currentFrame.pop(); ref.setField(i.concrete, value); } catch (Exception e) { e.printStackTrace(); } checkAndSetException(); } public void visitBIPUSH(BIPUSH inst) { currentFrame.push(new IntValue(inst.value)); } public void visitCALOAD(CALOAD inst) { try { IntValue i1 = (IntValue) currentFrame.pop(); ObjectValue ref = (ObjectValue) currentFrame.pop(); Value val = ref.getField(i1.concrete); currentFrame.push(getArrayElementInt(inst.iid, ref, i1, val)); } catch (Exception e) { e.printStackTrace(); } checkAndSetException(); } public void visitCASTORE(CASTORE inst) { try { Value value = currentFrame.pop(); IntValue i = (IntValue) currentFrame.pop(); ObjectValue ref = (ObjectValue) currentFrame.pop(); ref.setField(i.concrete, value); } catch (Exception e) { e.printStackTrace(); } checkAndSetException(); } public void visitCHECKCAST(CHECKCAST inst) { checkAndSetException(); } public void visitD2F(D2F inst) { DoubleValue d1 = (DoubleValue) currentFrame.pop2(); currentFrame.push(d1.D2F()); } public void visitD2I(D2I inst) { DoubleValue d1 = (DoubleValue) currentFrame.pop2(); currentFrame.push(d1.D2I()); } public void visitD2L(D2L inst) { DoubleValue d1 = (DoubleValue) currentFrame.pop2(); currentFrame.push2(d1.D2L()); } public void visitDADD(DADD inst) { DoubleValue d2 = (DoubleValue) currentFrame.pop2(); DoubleValue d1 = (DoubleValue) currentFrame.pop2(); currentFrame.push2(d1.DADD(d2)); } public void visitDALOAD(DALOAD inst) { try { IntValue i1 = (IntValue) currentFrame.pop(); ObjectValue ref = (ObjectValue) currentFrame.pop(); currentFrame.push2(ref.getField(i1.concrete)); } catch (Exception e) { e.printStackTrace(); } checkAndSetException(); } public void visitDASTORE(DASTORE inst) { try { Value value = currentFrame.pop2(); IntValue i = (IntValue) currentFrame.pop(); ObjectValue ref = (ObjectValue) currentFrame.pop(); ref.setField(i.concrete, value); } catch (Exception e) { e.printStackTrace(); } checkAndSetException(); } public void visitDCMPG(DCMPG inst) { DoubleValue d2 = (DoubleValue) currentFrame.pop2(); DoubleValue d1 = (DoubleValue) currentFrame.pop2(); currentFrame.push(d1.DCMPG(d2)); } public void visitDCMPL(DCMPL inst) { DoubleValue d2 = (DoubleValue) currentFrame.pop2(); DoubleValue d1 = (DoubleValue) currentFrame.pop2(); currentFrame.push(d1.DCMPL(d2)); } public void visitDCONST_0(DCONST_0 inst) { currentFrame.push2(new DoubleValue(0.0)); } public void visitDCONST_1(DCONST_1 inst) { currentFrame.push2(new DoubleValue(1.0)); } public void visitDDIV(DDIV inst) { DoubleValue d2 = (DoubleValue) currentFrame.pop2(); DoubleValue d1 = (DoubleValue) currentFrame.pop2(); currentFrame.push2(d1.DDIV(d2)); } public void visitDLOAD(DLOAD inst) { currentFrame.push2(currentFrame.getLocal2(inst.var)); } public void visitDMUL(DMUL inst) { DoubleValue d2 = (DoubleValue) currentFrame.pop2(); DoubleValue d1 = (DoubleValue) currentFrame.pop2(); currentFrame.push2(d1.DMUL(d2)); } public void visitDNEG(DNEG inst) { DoubleValue d1 = (DoubleValue) currentFrame.pop2(); currentFrame.push2(d1.DNEG()); } public void visitDREM(DREM inst) { DoubleValue d2 = (DoubleValue) currentFrame.pop2(); DoubleValue d1 = (DoubleValue) currentFrame.pop2(); currentFrame.push2(d1.DREM(d2)); } public void visitDRETURN(DRETURN inst) { currentFrame.setRet(currentFrame.pop2()); } public void visitDSTORE(DSTORE inst) { currentFrame.setLocal2(inst.var, currentFrame.pop2()); } public void visitDSUB(DSUB inst) { DoubleValue d2 = (DoubleValue) currentFrame.pop2(); DoubleValue d1 = (DoubleValue) currentFrame.pop2(); currentFrame.push2(d1.DSUB(d2)); } public void visitDUP(DUP inst) { currentFrame.push(currentFrame.peek()); } public void visitDUP2(DUP2 inst) { currentFrame.push(currentFrame.peek2()); currentFrame.push(currentFrame.peek2()); } public void visitDUP2_X1(DUP2_X1 inst) { Value word1 = currentFrame.pop(); Value word2 = currentFrame.pop(); Value word3 = currentFrame.pop(); currentFrame.push(word2); currentFrame.push(word1); currentFrame.push(word3); currentFrame.push(word2); currentFrame.push(word1); } public void visitDUP2_X2(DUP2_X2 inst) { Value word1 = currentFrame.pop(); Value word2 = currentFrame.pop(); Value word3 = currentFrame.pop(); Value word4 = currentFrame.pop(); currentFrame.push(word2); currentFrame.push(word1); currentFrame.push(word4); currentFrame.push(word3); currentFrame.push(word2); currentFrame.push(word1); } public void visitDUP_X1(DUP_X1 inst) { Value top = currentFrame.pop(); Value top2 = currentFrame.pop(); currentFrame.push(top); currentFrame.push(top2); currentFrame.push(top); } public void visitDUP_X2(DUP_X2 inst) { Value word1 = currentFrame.pop(); Value word2 = currentFrame.pop(); Value word3 = currentFrame.pop(); currentFrame.push(word1); currentFrame.push(word3); currentFrame.push(word2); currentFrame.push(word1); } public void visitF2D(F2D inst) { FloatValue f1 = (FloatValue) currentFrame.pop(); currentFrame.push2(f1.F2D()); } public void visitF2I(F2I inst) { FloatValue f1 = (FloatValue) currentFrame.pop(); currentFrame.push(f1.F2I()); } public void visitF2L(F2L inst) { FloatValue f1 = (FloatValue) currentFrame.pop(); currentFrame.push2(f1.F2L()); } public void visitFADD(FADD inst) { FloatValue f2 = (FloatValue) currentFrame.pop(); FloatValue f1 = (FloatValue) currentFrame.pop(); currentFrame.push(f1.FADD(f2)); } public void visitFALOAD(FALOAD inst) { try { IntValue i1 = (IntValue) currentFrame.pop(); ObjectValue ref = (ObjectValue) currentFrame.pop(); currentFrame.push(ref.getField(i1.concrete)); } catch (Exception e) { e.printStackTrace(); } checkAndSetException(); } public void visitFASTORE(FASTORE inst) { try { Value value = currentFrame.pop(); IntValue i = (IntValue) currentFrame.pop(); ObjectValue ref = (ObjectValue) currentFrame.pop(); ref.setField(i.concrete, value); } catch (Exception e) { e.printStackTrace(); } checkAndSetException(); } public void visitFCMPG(FCMPG inst) { FloatValue f2 = (FloatValue) currentFrame.pop(); FloatValue f1 = (FloatValue) currentFrame.pop(); currentFrame.push(f1.FCMPG(f2)); } public void visitFCMPL(FCMPL inst) { FloatValue f2 = (FloatValue) currentFrame.pop(); FloatValue f1 = (FloatValue) currentFrame.pop(); currentFrame.push(f1.FCMPL(f2)); } public void visitFCONST_0(FCONST_0 inst) { currentFrame.push(new FloatValue(0.0f)); } public void visitFCONST_1(FCONST_1 inst) { currentFrame.push(new FloatValue(1.0f)); } public void visitFCONST_2(FCONST_2 inst) { currentFrame.push(new FloatValue(2.0f)); } public void visitFDIV(FDIV inst) { FloatValue f2 = (FloatValue) currentFrame.pop(); FloatValue f1 = (FloatValue) currentFrame.pop(); currentFrame.push(f1.FDIV(f2)); } public void visitFLOAD(FLOAD inst) { currentFrame.push(currentFrame.getLocal(inst.var)); } public void visitFMUL(FMUL inst) { FloatValue f2 = (FloatValue) currentFrame.pop(); FloatValue f1 = (FloatValue) currentFrame.pop(); currentFrame.push(f1.FMUL(f2)); } public void visitFNEG(FNEG inst) { FloatValue f1 = (FloatValue) currentFrame.pop(); currentFrame.push(f1.FNEG()); } public void visitFREM(FREM inst) { FloatValue f2 = (FloatValue) currentFrame.pop(); FloatValue f1 = (FloatValue) currentFrame.pop(); currentFrame.push(f1.FREM(f2)); } public void visitFRETURN(FRETURN inst) { currentFrame.setRet(currentFrame.pop()); } public void visitFSTORE(FSTORE inst) { currentFrame.setLocal(inst.var, currentFrame.pop()); } public void visitFSUB(FSUB inst) { FloatValue f2 = (FloatValue) currentFrame.pop(); FloatValue f1 = (FloatValue) currentFrame.pop(); currentFrame.push(f1.FSUB(f2)); } public void visitGETFIELD(GETFIELD inst) { try { ObjectInfo oi = cnames.get(inst.cIdx); FieldInfo fi = oi.get(inst.fIdx, false); ObjectValue ref = (ObjectValue) currentFrame.pop(); if (inst.desc.startsWith("D") || inst.desc.startsWith("J")) { currentFrame.push2(ref.getField(fi.getFieldId())); } else { currentFrame.push(ref.getField(fi.getFieldId())); } } catch (Exception e) { e.printStackTrace(); } checkAndSetException(); } public void visitGETSTATIC(GETSTATIC inst) { try { ObjectInfo oi = cnames.get(inst.cIdx); FieldInfo fi = oi.get(inst.fIdx, true); if (inst.desc.startsWith("D") || inst.desc.startsWith("J")) { currentFrame.push2(oi.getStaticField(fi.getFieldId())); } else { currentFrame.push(oi.getStaticField(fi.getFieldId())); } } catch (Exception e) { e.printStackTrace(); } checkAndSetException(); } public void visitGETVALUE_Object(GETVALUE_Object inst) { Value peek = currentFrame.peek(); Value tmp; if (peek == PlaceHolder.instance || (((ObjectValue) peek).address != ADDRESS_UNKNOWN && ((ObjectValue) peek).address != inst.v)) { logger.log(Level.FINE, "** Failed to match " + currentFrame.peek() + " and " + inst.v); currentFrame.pop(); tmp = objects.get(inst.v); if (tmp != null) { currentFrame.push(tmp); } else if (inst.v == 0) { currentFrame.push(ObjectValue.NULL); } else { if (inst.isString) { currentFrame.push(tmp = new StringValue(inst.string, inst.v)); } else { currentFrame.push(tmp = new ObjectValue(100, inst.v)); } objects.put(inst.v, tmp); } } else if (((ObjectValue) peek).address == ADDRESS_UNKNOWN) { // set the address of the object if (inst.v == 0) { logger.log(Level.FINE, "** Failed to match {0} and " + inst.v, currentFrame.peek()); currentFrame.pop(); currentFrame.push(ObjectValue.NULL); } else { // Need to obtain the Object address ((ObjectValue) peek).setAddress(inst.v); objects.put(inst.v, peek); } } } public void visitGETVALUE_boolean(GETVALUE_boolean inst) { if (currentFrame.peek() == PlaceHolder.instance || ((IntValue) currentFrame.peek()).concrete != (inst.v ? 1 : 0)) { logger.log(Level.FINE, "** Failed to match {0} and " + inst.v, currentFrame.peek()); currentFrame.pop(); currentFrame.push(new IntValue(inst.v ? 1 : 0)); } } public void visitGETVALUE_byte(GETVALUE_byte inst) { if (currentFrame.peek() == PlaceHolder.instance || ((IntValue) currentFrame.peek()).concrete != inst.v) { logger.log(Level.FINE, "** Failed to match {0} and " + inst.v, currentFrame.peek()); currentFrame.pop(); currentFrame.push(new IntValue(inst.v)); } } public void visitGETVALUE_char(GETVALUE_char inst) { if (currentFrame.peek() == PlaceHolder.instance || ((IntValue) currentFrame.peek()).concrete != inst.v) { logger.log(Level.FINE, "** Failed to match {0} and " + inst.v, currentFrame.peek()); currentFrame.pop(); currentFrame.push(new IntValue(inst.v)); } } public void visitGETVALUE_double(GETVALUE_double inst) { if (currentFrame.peek2() == PlaceHolder.instance || ((DoubleValue) currentFrame.peek2()).concrete != inst.v) { logger.log(Level.FINE, "** Failed to match {0} and " + inst.v, currentFrame.peek()); currentFrame.pop2(); currentFrame.push2(new DoubleValue(inst.v)); } } public void visitGETVALUE_float(GETVALUE_float inst) { if (currentFrame.peek() == PlaceHolder.instance || ((FloatValue) currentFrame.peek()).concrete != inst.v) { logger.log(Level.FINE, "** Failed to match {0} and " + inst.v, currentFrame.peek()); currentFrame.pop(); currentFrame.push(new FloatValue(inst.v)); } } public void visitGETVALUE_int(GETVALUE_int inst) { if (currentFrame.peek() == PlaceHolder.instance || ((IntValue) currentFrame.peek()).concrete != inst.v) { logger.log(Level.FINE, "** Failed to match {0} and " + inst.v, currentFrame.peek()); currentFrame.pop(); currentFrame.push(new IntValue(inst.v)); } } public void visitGETVALUE_long(GETVALUE_long inst) { if (currentFrame.peek2() == PlaceHolder.instance || ((LongValue) currentFrame.peek2()).getConcreteLong() != inst.v) { logger.log(Level.FINE, "** Failed to match {0} and " + inst.v, currentFrame.peek()); currentFrame.pop2(); currentFrame.push2(new LongValue(inst.v)); } } public void visitGETVALUE_short(GETVALUE_short inst) { if (currentFrame.peek() == PlaceHolder.instance || ((IntValue) currentFrame.peek()).concrete != inst.v) { logger.log(Level.FINE, "** Failed to match {0} and " + inst.v, currentFrame.peek()); currentFrame.pop(); currentFrame.push(new IntValue(inst.v)); } } public void visitGETVALUE_void(GETVALUE_void inst) {} public void visitGOTO(GOTO inst) {} public void visitI2B(I2B inst) { IntValue i1 = (IntValue) currentFrame.pop(); currentFrame.push(i1.I2B()); } public void visitI2C(I2C inst) { IntValue i1 = (IntValue) currentFrame.pop(); currentFrame.push(i1.I2C()); } public void visitI2D(I2D inst) { IntValue i1 = (IntValue) currentFrame.pop(); currentFrame.push2(i1.I2D()); } public void visitI2F(I2F inst) { IntValue i1 = (IntValue) currentFrame.pop(); currentFrame.push(i1.I2F()); } public void visitI2L(I2L inst) { IntValue i1 = (IntValue) currentFrame.pop(); currentFrame.push2(i1.I2L()); } public void visitI2S(I2S inst) { IntValue i1 = (IntValue) currentFrame.pop(); currentFrame.push(i1.I2S()); } public void visitIADD(IADD inst) { IntValue i2 = (IntValue) currentFrame.pop(); IntValue i1 = (IntValue) currentFrame.pop(); currentFrame.push(i1.IADD(i2)); } public void visitIALOAD(IALOAD inst) { try { IntValue i1 = (IntValue) currentFrame.pop(); ObjectValue ref = (ObjectValue) currentFrame.pop(); Value val = ref.getField(i1.concrete); currentFrame.push(getArrayElementInt(inst.iid, ref, i1, val)); } catch (Exception e) { e.printStackTrace(); } checkAndSetException(); } public void visitIAND(IAND inst) { IntValue i2 = (IntValue) currentFrame.pop(); IntValue i1 = (IntValue) currentFrame.pop(); currentFrame.push(i1.IAND(i2)); } public void visitIASTORE(IASTORE inst) { try { Value value = currentFrame.pop(); IntValue i = (IntValue) currentFrame.pop(); ObjectValue ref = (ObjectValue) currentFrame.pop(); ref.setField(i.concrete, value); } catch (Exception e) { e.printStackTrace(); } checkAndSetException(); } public void visitICONST_0(ICONST_0 inst) { currentFrame.push(new IntValue(0)); } public void visitICONST_1(ICONST_1 inst) { currentFrame.push(new IntValue(1)); } public void visitICONST_2(ICONST_2 inst) { currentFrame.push(new IntValue(2)); } public void visitICONST_3(ICONST_3 inst) { currentFrame.push(new IntValue(3)); } public void visitICONST_4(ICONST_4 inst) { currentFrame.push(new IntValue(4)); } public void visitICONST_5(ICONST_5 inst) { currentFrame.push(new IntValue(5)); } public void visitICONST_M1(ICONST_M1 inst) { currentFrame.push(new IntValue(-1)); } public void visitIDIV(IDIV inst) { try { IntValue i2 = (IntValue) currentFrame.pop(); IntValue i1 = (IntValue) currentFrame.pop(); currentFrame.push(i1.IDIV(i2)); } catch (Exception e) { e.printStackTrace(); } checkAndSetException(); } public void visitIFEQ(IFEQ inst) { IntValue i1 = (IntValue) currentFrame.pop(); IntValue result = i1.IFEQ(); checkAndSetBranch(result); history.checkAndSetBranch(result.concrete == 1, result.getSymbolic(), inst.iid); coverage.visitBranch(inst.iid, result.concrete == 1); } public void visitIFGE(IFGE inst) { IntValue i1 = (IntValue) currentFrame.pop(); IntValue result = i1.IFGE(); checkAndSetBranch(result); history.checkAndSetBranch(result.concrete == 1, result.symbolic, inst.iid); coverage.visitBranch(inst.iid, result.concrete == 1); } public void visitIFGT(IFGT inst) { IntValue i1 = (IntValue) currentFrame.pop(); IntValue result = i1.IFGT(); checkAndSetBranch(result); history.checkAndSetBranch(result.concrete == 1, result.symbolic, inst.iid); coverage.visitBranch(inst.iid, result.concrete == 1); } public void visitIFLE(IFLE inst) { IntValue i1 = (IntValue) currentFrame.pop(); IntValue result = i1.IFLE(); checkAndSetBranch(result); history.checkAndSetBranch(result.concrete == 1, result.symbolic, inst.iid); coverage.visitBranch(inst.iid, result.concrete == 1); } public void visitIFLT(IFLT inst) { IntValue i1 = (IntValue) currentFrame.pop(); IntValue result = i1.IFLT(); checkAndSetBranch(result); history.checkAndSetBranch(result.concrete == 1, result.symbolic, inst.iid); coverage.visitBranch(inst.iid, result.concrete == 1); } public void visitIFNE(IFNE inst) { IntValue i1 = (IntValue) currentFrame.pop(); IntValue result = i1.IFNE(); checkAndSetBranch(result); history.checkAndSetBranch(result.concrete == 1, result.getSymbolic(), inst.iid); coverage.visitBranch(inst.iid, result.concrete == 1); } public void visitIFNONNULL(IFNONNULL inst) { ObjectValue o1 = (ObjectValue) currentFrame.pop(); IntValue result = o1.IFNONNULL(); checkAndSetBranch(result); history.checkAndSetBranch(result.concrete == 1, result.symbolic, inst.iid); coverage.visitBranch(inst.iid, result.concrete == 1); } public void visitIFNULL(IFNULL inst) { ObjectValue o1 = (ObjectValue) currentFrame.pop(); IntValue result = o1.IFNULL(); checkAndSetBranch(result); history.checkAndSetBranch(result.concrete == 1, result.symbolic, inst.iid); coverage.visitBranch(inst.iid, result.concrete == 1); } public void visitIF_ACMPEQ(IF_ACMPEQ inst) { ObjectValue o2 = (ObjectValue) currentFrame.pop(); ObjectValue o1 = (ObjectValue) currentFrame.pop(); IntValue result = o1.IF_ACMPEQ(o2); checkAndSetBranch(result); history.checkAndSetBranch(result.concrete == 1, result.symbolic, inst.iid); coverage.visitBranch(inst.iid, result.concrete == 1); } public void visitIF_ACMPNE(IF_ACMPNE inst) { ObjectValue o2 = (ObjectValue) currentFrame.pop(); ObjectValue o1 = (ObjectValue) currentFrame.pop(); IntValue result = o1.IF_ACMPNE(o2); checkAndSetBranch(result); history.checkAndSetBranch(result.concrete == 1, result.symbolic, inst.iid); coverage.visitBranch(inst.iid, result.concrete == 1); } public void visitIF_ICMPEQ(IF_ICMPEQ inst) { IntValue i2 = (IntValue) currentFrame.pop(); IntValue i1 = (IntValue) currentFrame.pop(); IntValue result = i1.IF_ICMPEQ(i2); checkAndSetBranch(result); history.checkAndSetBranch(result.concrete == 1, result.symbolic, inst.iid); coverage.visitBranch(inst.iid, result.concrete == 1); } public void visitIF_ICMPGE(IF_ICMPGE inst) { IntValue i2 = (IntValue) currentFrame.pop(); IntValue i1 = (IntValue) currentFrame.pop(); IntValue result = i1.IF_ICMPGE(i2); checkAndSetBranch(result); history.checkAndSetBranch(result.concrete == 1, result.symbolic, inst.iid); coverage.visitBranch(inst.iid, result.concrete == 1); } public void visitIF_ICMPGT(IF_ICMPGT inst) { IntValue i2 = (IntValue) currentFrame.pop(); IntValue i1 = (IntValue) currentFrame.pop(); IntValue result = i1.IF_ICMPGT(i2); checkAndSetBranch(result); history.checkAndSetBranch(result.concrete == 1, result.symbolic, inst.iid); coverage.visitBranch(inst.iid, result.concrete == 1); } public void visitIF_ICMPLE(IF_ICMPLE inst) { IntValue i2 = (IntValue) currentFrame.pop(); IntValue i1 = (IntValue) currentFrame.pop(); IntValue result = i1.IF_ICMPLE(i2); checkAndSetBranch(result); history.checkAndSetBranch(result.concrete == 1, result.symbolic, inst.iid); coverage.visitBranch(inst.iid, result.concrete == 1); } public void visitIF_ICMPLT(IF_ICMPLT inst) { IntValue i2 = (IntValue) currentFrame.pop(); IntValue i1 = (IntValue) currentFrame.pop(); IntValue result = i1.IF_ICMPLT(i2); checkAndSetBranch(result); history.checkAndSetBranch(result.concrete == 1L, result.symbolic, inst.iid); coverage.visitBranch(inst.iid, result.concrete == 1); } public void visitIF_ICMPNE(IF_ICMPNE inst) { IntValue i2 = (IntValue) currentFrame.pop(); IntValue i1 = (IntValue) currentFrame.pop(); IntValue result = i1.IF_ICMPNE(i2); checkAndSetBranch(result); history.checkAndSetBranch(result.concrete == 1, result.symbolic, inst.iid); coverage.visitBranch(inst.iid, result.concrete == 1); } public void visitIINC(IINC inst) { IntValue i1 = (IntValue) currentFrame.getLocal(inst.var); currentFrame.setLocal(inst.var, i1.IINC(inst.increment)); } public void visitILOAD(ILOAD inst) { currentFrame.push(currentFrame.getLocal(inst.var)); } public void visitIMUL(IMUL inst) { IntValue i2 = (IntValue) currentFrame.pop(); IntValue i1 = (IntValue) currentFrame.pop(); currentFrame.push(i1.IMUL(i2)); } public void visitINEG(INEG inst) { IntValue i1 = (IntValue) currentFrame.pop(); currentFrame.push(i1.INEG()); } public void visitINSTANCEOF(INSTANCEOF inst) { try { currentFrame.pop(); currentFrame.push(new IntValue(1)); // could be wrong boolean value } catch (Exception e) { e.printStackTrace(); } checkAndSetException(); } private void setArgumentsAndNewFrame( String desc, String owner, String name, boolean isInstance, Instruction inst) { Type[] types = Type.getArgumentTypes(desc); Type retType = Type.getReturnType(desc); int nReturnWords; if (retType == Type.DOUBLE_TYPE || retType == Type.LONG_TYPE) { nReturnWords = 2; } else if (retType == Type.VOID_TYPE) { nReturnWords = 0; } else { nReturnWords = 1; } Frame tmp = new Frame(nReturnWords); stack.push(tmp); int len = types.length; Value[] tmpValues = new Value[len]; for (int i = len - 1; i >= 0; i--) { if (types[i] == Type.DOUBLE_TYPE || types[i] == Type.LONG_TYPE) { tmpValues[i] = currentFrame.pop2(); } else { tmpValues[i] = currentFrame.pop(); } } ObjectValue instance = null; if (isInstance) { instance = (ObjectValue) currentFrame.pop(); tmp.addLocal(instance); } for (int i = 0; i < len; i++) { if (types[i] == Type.DOUBLE_TYPE || types[i] == Type.LONG_TYPE) { tmp.addLocal2(tmpValues[i]); } else { tmp.addLocal(tmpValues[i]); } } currentFrame = tmp; if (next instanceof INVOKEMETHOD_END || next instanceof INVOKEMETHOD_EXCEPTION || next == null) { if (isInstance) { currentFrame.setRet(instance.invokeMethod(name, tmpValues, history)); } else { currentFrame.setRet(staticInv.invokeMethod(inst.iid, owner, name, tmpValues, history)); } } } public void visitINVOKEINTERFACE(INVOKEINTERFACE inst) { setArgumentsAndNewFrame(inst.desc, inst.owner, inst.name, true, inst); } public void visitINVOKESPECIAL(INVOKESPECIAL inst) { setArgumentsAndNewFrame(inst.desc, inst.owner, inst.name, true, inst); } public void visitINVOKESTATIC(INVOKESTATIC inst) { setArgumentsAndNewFrame(inst.desc, inst.owner, inst.name, false, inst); } public void visitINVOKEVIRTUAL(INVOKEVIRTUAL inst) { setArgumentsAndNewFrame(inst.desc, inst.owner, inst.name, true, inst); } public void visitIOR(IOR inst) { IntValue i2 = (IntValue) currentFrame.pop(); IntValue i1 = (IntValue) currentFrame.pop(); currentFrame.push(i1.IOR(i2)); } public void visitIREM(IREM inst) { try { IntValue i2 = (IntValue) currentFrame.pop(); IntValue i1 = (IntValue) currentFrame.pop(); currentFrame.push(i1.IREM(i2)); } catch (Exception e) { e.printStackTrace(); } checkAndSetException(); } public void visitIRETURN(IRETURN inst) { currentFrame.setRet(currentFrame.pop()); } public void visitISHL(ISHL inst) { IntValue i2 = (IntValue) currentFrame.pop(); IntValue i1 = (IntValue) currentFrame.pop(); currentFrame.push(i1.ISHL(i2)); } public void visitISHR(ISHR inst) { IntValue i2 = (IntValue) currentFrame.pop(); IntValue i1 = (IntValue) currentFrame.pop(); currentFrame.push(i1.ISHR(i2)); } public void visitISTORE(ISTORE inst) { currentFrame.setLocal(inst.var, currentFrame.pop()); } public void visitISUB(ISUB inst) { IntValue i2 = (IntValue) currentFrame.pop(); IntValue i1 = (IntValue) currentFrame.pop(); currentFrame.push(i1.ISUB(i2)); } public void visitIUSHR(IUSHR inst) { IntValue i2 = (IntValue) currentFrame.pop(); IntValue i1 = (IntValue) currentFrame.pop(); currentFrame.push(i1.IUSHR(i2)); } public void visitIXOR(IXOR inst) { IntValue i2 = (IntValue) currentFrame.pop(); IntValue i1 = (IntValue) currentFrame.pop(); currentFrame.push(i1.IXOR(i2)); } public void visitJSR(JSR inst) {} public void visitL2D(L2D inst) { LongValue i1 = (LongValue) currentFrame.pop2(); currentFrame.push2(i1.L2D()); } public void visitL2F(L2F inst) { LongValue i1 = (LongValue) currentFrame.pop2(); currentFrame.push(i1.L2F()); } public void visitL2I(L2I inst) { LongValue i1 = (LongValue) currentFrame.pop2(); currentFrame.push(i1.L2I()); } public void visitLADD(LADD inst) { LongValue i2 = (LongValue) currentFrame.pop2(); LongValue i1 = (LongValue) currentFrame.pop2(); currentFrame.push2(i1.LADD(i2)); } public void visitLALOAD(LALOAD inst) { try { IntValue i1 = (IntValue) currentFrame.pop(); ObjectValue ref = (ObjectValue) currentFrame.pop(); Value val = ref.getField(i1.concrete); currentFrame.push2(getArrayElementLong(inst.iid, ref, i1, val)); } catch (Exception e) { e.printStackTrace(); } checkAndSetException(); } public void visitLAND(LAND inst) { LongValue i2 = (LongValue) currentFrame.pop2(); LongValue i1 = (LongValue) currentFrame.pop2(); currentFrame.push2(i1.LAND(i2)); } public void visitLASTORE(LASTORE inst) { try { Value value = currentFrame.pop2(); IntValue i = (IntValue) currentFrame.pop(); ObjectValue ref = (ObjectValue) currentFrame.pop(); ref.setField(i.concrete, value); } catch (Exception e) { e.printStackTrace(); } checkAndSetException(); } public void visitLCMP(LCMP inst) { LongValue i2 = (LongValue) currentFrame.pop2(); LongValue i1 = (LongValue) currentFrame.pop2(); currentFrame.push(i1.LCMP(i2)); } public void visitLCONST_0(LCONST_0 inst) { currentFrame.push2(new LongValue(0)); } public void visitLCONST_1(LCONST_1 inst) { currentFrame.push2(new LongValue(1)); } public void visitLDC_String(LDC_String inst) { currentFrame.push(new StringValue(inst.c, inst.address)); } public void visitLDC_Object(LDC_Object inst) { Value tmp = objects.get(inst.c); if (tmp != null) { currentFrame.push(tmp); } else if (inst.c == 0) { currentFrame.push(ObjectValue.NULL); } else { currentFrame.push(tmp = new ObjectValue(100, inst.c)); objects.put(inst.c, tmp); } } public void visitLDC_double(LDC_double inst) { currentFrame.push2(new DoubleValue(inst.c)); } public void visitLDC_float(LDC_float inst) { currentFrame.push(new FloatValue(inst.c)); } public void visitLDC_int(LDC_int inst) { currentFrame.push(new IntValue(inst.c)); } public void visitLDC_long(LDC_long inst) { currentFrame.push2(new LongValue(inst.c)); } public void visitLDIV(LDIV inst) { try { LongValue i2 = (LongValue) currentFrame.pop2(); LongValue i1 = (LongValue) currentFrame.pop2(); currentFrame.push2(i1.LDIV(i2)); } catch (Exception e) { e.printStackTrace(); } checkAndSetException(); } public void visitLLOAD(LLOAD inst) { currentFrame.push2(currentFrame.getLocal2(inst.var)); } public void visitLMUL(LMUL inst) { LongValue i2 = (LongValue) currentFrame.pop2(); LongValue i1 = (LongValue) currentFrame.pop2(); currentFrame.push2(i1.LMUL(i2)); } public void visitLNEG(LNEG inst) { LongValue i1 = (LongValue) currentFrame.pop2(); currentFrame.push2(i1.LNEG()); } public void visitLOR(LOR inst) { LongValue i2 = (LongValue) currentFrame.pop2(); LongValue i1 = (LongValue) currentFrame.pop2(); currentFrame.push2(i1.LOR(i2)); } public void visitLREM(LREM inst) { try { LongValue i2 = (LongValue) currentFrame.pop2(); LongValue i1 = (LongValue) currentFrame.pop2(); currentFrame.push2(i1.LREM(i2)); } catch (Exception e) { e.printStackTrace(); } checkAndSetException(); } public void visitLRETURN(LRETURN inst) { currentFrame.setRet(currentFrame.pop2()); } public void visitLSHL(LSHL inst) { LongValue i2 = (LongValue) currentFrame.pop2(); LongValue i1 = (LongValue) currentFrame.pop2(); currentFrame.push2(i1.LSHL(i2)); } public void visitLSHR(LSHR inst) { LongValue i2 = (LongValue) currentFrame.pop2(); LongValue i1 = (LongValue) currentFrame.pop2(); currentFrame.push2(i1.LSHR(i2)); } public void visitLSTORE(LSTORE inst) { currentFrame.setLocal2(inst.var, currentFrame.pop2()); } public void visitLSUB(LSUB inst) { LongValue i2 = (LongValue) currentFrame.pop2(); LongValue i1 = (LongValue) currentFrame.pop2(); currentFrame.push2(i1.LSUB(i2)); } public void visitLUSHR(LUSHR inst) { LongValue i2 = (LongValue) currentFrame.pop2(); LongValue i1 = (LongValue) currentFrame.pop2(); currentFrame.push2(i1.LUSHR(i2)); } public void visitLXOR(LXOR inst) { LongValue i2 = (LongValue) currentFrame.pop2(); LongValue i1 = (LongValue) currentFrame.pop2(); currentFrame.push2(i1.LXOR(i2)); } public void visitMONITORENTER(MONITORENTER inst) { checkAndSetException(); } public void visitMONITOREXIT(MONITOREXIT inst) { checkAndSetException(); } public void visitNEW(NEW inst) { try { ObjectInfo oi = cnames.get(inst.cIdx); currentFrame.push(ObjectFactory.create(oi.getNFields(), oi.getClassName())); } catch (Exception e) { e.printStackTrace(); } } public void visitNEWARRAY(NEWARRAY inst) { try { IntValue i1 = (IntValue) currentFrame.pop(); ObjectValue tmp = new ObjectValue(i1.concrete); currentFrame.push(tmp); } catch (Exception e) { e.printStackTrace(); } checkAndSetException(); } public void visitNOP(NOP inst) {} public void visitPOP(POP inst) { currentFrame.pop(); } public void visitPOP2(POP2 inst) { currentFrame.pop2(); } public void visitPUTFIELD(PUTFIELD inst) { try { ObjectInfo oi = cnames.get(inst.cIdx); FieldInfo fi = oi.get(inst.fIdx, false); Value value; if (inst.desc.startsWith("D") || inst.desc.startsWith("J")) { value = currentFrame.pop2(); } else { value = currentFrame.pop(); } ObjectValue ref = (ObjectValue) currentFrame.pop(); ref.setField(fi.getFieldId(), value); } catch (Exception e) { e.printStackTrace(); } checkAndSetException(); } public void visitPUTSTATIC(PUTSTATIC inst) { try { ObjectInfo oi = cnames.get(inst.cIdx); FieldInfo fi = oi.get(inst.fIdx, true); Value value; if (inst.desc.startsWith("D") || inst.desc.startsWith("J")) { value = currentFrame.pop2(); } else { value = currentFrame.pop(); } oi.setStaticField(fi.getFieldId(), value); } catch (Exception e) { e.printStackTrace(); } checkAndSetException(); } public void visitRET(RET inst) { // throw new RuntimeException("Unimplemented instruction "+inst); } public void visitRETURN(RETURN inst) {} public void visitSALOAD(SALOAD inst) { try { IntValue i1 = (IntValue) currentFrame.pop(); ObjectValue ref = (ObjectValue) currentFrame.pop(); Value val = ref.getField(i1.concrete); currentFrame.push(getArrayElementInt(inst.iid, ref, i1, val)); } catch (Exception e) { e.printStackTrace(); } checkAndSetException(); } public void visitSASTORE(SASTORE inst) { try { Value value = currentFrame.pop(); IntValue i = (IntValue) currentFrame.pop(); ObjectValue ref = (ObjectValue) currentFrame.pop(); ref.setField(i.concrete, value); } catch (Exception e) { e.printStackTrace(); } checkAndSetException(); } public void visitSIPUSH(SIPUSH inst) { currentFrame.push(new IntValue(inst.value)); } public void visitSWAP(SWAP inst) { Value v1 = currentFrame.pop(); Value v2 = currentFrame.pop(); currentFrame.push(v1); currentFrame.push(v2); } public void visitINVOKEMETHOD_EXCEPTION(INVOKEMETHOD_EXCEPTION inst) { stack.pop(); currentFrame = stack.peek(); currentFrame.clear(); currentFrame.push(PlaceHolder.instance); // placeholder for the exception object } public void visitINVOKEMETHOD_END(INVOKEMETHOD_END inst) { Frame old = stack.pop(); currentFrame = stack.peek(); if (old.nReturnWords == 2) { currentFrame.push2(old.getRet()); } else if (old.nReturnWords == 1) { currentFrame.push(old.getRet()); } } public void visitMAKE_SYMBOLIC(MAKE_SYMBOLIC inst) { } public void visitSPECIAL(SPECIAL inst) { } public void setNext(Instruction next) { this.next = next; } private ObjectValue initMultiArray(int[] dims, int idx) { ObjectValue tmp = new ObjectValue(dims[idx]); if (idx < dims.length - 1) { for (int i = 0; i < dims[idx]; i++) { tmp.getFields()[i] = initMultiArray(dims, idx + 1); } } return tmp; } public void visitMULTIANEWARRAY(MULTIANEWARRAY inst) { int dims[] = new int[inst.dims]; try { for (int i = 0; i < dims.length; i++) { IntValue i1 = (IntValue) currentFrame.pop(); dims[dims.length - i - 1] = i1.concrete; } ObjectValue tmp = initMultiArray(dims, 0); currentFrame.push(tmp); } catch (Exception e) { e.printStackTrace(); } } public void visitLOOKUPSWITCH(LOOKUPSWITCH inst) { int[] keys = inst.keys; IntValue i1 = (IntValue) currentFrame.pop(); int i = 0; for (int key : keys) { IntValue result = i1.IF_ICMPEQ(new IntValue(key)); history.checkAndSetBranch(result.concrete == 1, result.symbolic, inst.iid); coverage.visitBranch(inst.iid + i, result.concrete == 1); if (result.concrete == 1) return; i++; } } public void visitTABLESWITCH(TABLESWITCH inst) { IntValue i1 = (IntValue) currentFrame.pop(); int j = 0; for (int i = inst.min; i <= inst.max; i++) { IntValue result = i1.IF_ICMPEQ(new IntValue(i)); history.checkAndSetBranch(result.concrete == 1, result.symbolic, inst.iid); coverage.visitBranch(inst.iid + j, result.concrete == 1); if (result.concrete == 1) return; j++; } } }