void printChoices() { int i = 0; SystemState ss = vm.getSystemState(); ChoiceGenerator<?>[] cgStack = ss.getChoiceGenerators(); nextChoice: for (ChoiceGenerator<?> cg : cgStack) { if (isRelevantCG(cg) && !cg.isDone()) { Object choice = cg.getNextChoice(); if (choice == null) { continue; } else { if (excludes != null) { for (String e : excludes) { if (choice.toString().startsWith(e)) { continue nextChoice; } } } } String line = null; switch (format) { case CHOICE: line = choice.toString(); if (line.startsWith("gov.nasa.jpf.jvm.")) { line = line.substring(17); } break; case CG: line = cg.toString(); if (line.startsWith("gov.nasa.jpf.jvm.choice.")) { line = line.substring(24); } break; } if (line != null) { pw.print(String.format("%4d: ", i++)); pw.print(line); if (showLocation) { String loc = cg.getSourceLocation(); if (loc != null) { pw.println(); pw.print(" \tat "); pw.print(loc); } } pw.println(); } } } }
public Instruction execute(SystemState ss, KernelState ks, ThreadInfo th) { RealExpression sym_fval = (RealExpression) th.getTopFrame().getOperandAttr(); if (sym_fval == null) { return super.execute(ss, ks, th); } else { // System.out.println("Execute symbolic F2L"); // here we get a hold of the current path condition and // add an extra mixed constraint sym_dval==sym_ival ChoiceGenerator<?> cg; if (!th.isFirstStepInsn()) { // first time around cg = new PCChoiceGenerator(1); // only one choice ss.setNextChoiceGenerator(cg); return this; } else { // this is what really returns results cg = ss.getChoiceGenerator(); assert (cg instanceof PCChoiceGenerator) : "expected PCChoiceGenerator, got: " + cg; } // get the path condition from the // previous choice generator of the same type PathCondition pc; ChoiceGenerator<?> prev_cg = cg.getPreviousChoiceGenerator(); while (!((prev_cg == null) || (prev_cg instanceof PCChoiceGenerator))) { prev_cg = prev_cg.getPreviousChoiceGenerator(); } if (prev_cg == null) pc = new PathCondition(); // TODO: handling of preconditions needs to be changed else pc = ((PCChoiceGenerator) prev_cg).getCurrentPC(); assert pc != null; th.pop(); th.longPush(0); // for symbolic expressions, the concrete value does not matter SymbolicInteger sym_lval = new SymbolicInteger(); StackFrame sf = th.getTopFrame(); sf.setLongOperandAttr(sym_lval); pc._addDet(Comparator.EQ, sym_fval, sym_lval); if (!pc.simplify()) { // not satisfiable ss.setIgnored(true); } else { // pc.solve(); ((PCChoiceGenerator) cg).setCurrentPC(pc); // System.out.println(((PCChoiceGenerator) cg).getCurrentPC()); } // System.out.println("Execute D2I: " + sf.getLongOperandAttr()); return getNext(th); } }
// Copied from PathCondition... protected void setPC(PathCondition pc) { JVM vm = JVM.getVM(); ChoiceGenerator<?> cg = vm.getChoiceGenerator(); if (cg != null && !(cg instanceof PCChoiceGenerator)) { cg = cg.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); } if (cg instanceof PCChoiceGenerator) { ((PCChoiceGenerator) cg).setCurrentPC(pc); System.err.println("AtomBuchiCG.setPc: " + pc); return; } assert false : "Can not set PC " + pc; }
// the purpose of this method is to set the PCheap to the "eq null" constraint for the input // specified w/ stringRef public static int makeSymbolicNull(MJIEnv env, int objRef, int stringRef) { // introduce a heap choice generator for the element in the heap ThreadInfo ti = env.getVM().getCurrentThread(); SystemState ss = env.getVM().getSystemState(); ChoiceGenerator<?> cg; if (!ti.isFirstStepInsn()) { cg = new HeapChoiceGenerator(1); // new ss.setNextChoiceGenerator(cg); env.repeatInvocation(); return -1; // not used anyways } // else this is what really returns results cg = ss.getChoiceGenerator(); assert (cg instanceof HeapChoiceGenerator) : "expected HeapChoiceGenerator, got: " + cg; // see if there were more inputs added before ChoiceGenerator<?> prevHeapCG = cg.getPreviousChoiceGenerator(); while (!((prevHeapCG == null) || (prevHeapCG instanceof HeapChoiceGenerator))) { prevHeapCG = prevHeapCG.getPreviousChoiceGenerator(); } PathCondition pcHeap; SymbolicInputHeap symInputHeap; if (prevHeapCG == null) { pcHeap = new PathCondition(); symInputHeap = new SymbolicInputHeap(); } else { pcHeap = ((HeapChoiceGenerator) prevHeapCG).getCurrentPCheap(); symInputHeap = ((HeapChoiceGenerator) prevHeapCG).getCurrentSymInputHeap(); } String name = env.getStringObject(stringRef); String refChain = name + "[-1]"; // why is the type used here? should use the name of the field instead SymbolicInteger newSymRef = new SymbolicInteger(refChain); // create new HeapNode based on above info // update associated symbolic input heap pcHeap._addDet(Comparator.EQ, newSymRef, new IntegerConstant(-1)); ((HeapChoiceGenerator) cg).setCurrentPCheap(pcHeap); ((HeapChoiceGenerator) cg).setCurrentSymInputHeap(symInputHeap); // System.out.println(">>>>>>>>>>>> initial pcHeap: " + pcHeap.toString()); return -1; }
public static PathCondition getPC(MJIEnv env) { JVM vm = env.getVM(); ChoiceGenerator<?> cg = vm.getChoiceGenerator(); PathCondition pc = null; if (!(cg instanceof PCChoiceGenerator)) { ChoiceGenerator<?> prev_cg = cg.getPreviousChoiceGenerator(); while (!((prev_cg == null) || (prev_cg instanceof PCChoiceGenerator))) { prev_cg = prev_cg.getPreviousChoiceGenerator(); } cg = prev_cg; } if ((cg instanceof PCChoiceGenerator) && cg != null) { pc = ((PCChoiceGenerator) cg).getCurrentPC(); } return pc; }
public static void printHeapPC(MJIEnv env, int objRef, int msgRef) { // should first solve the pc's!!!! JVM vm = env.getVM(); ChoiceGenerator<?> cg = vm.getChoiceGenerator(); PathCondition pc = null; if (!(cg instanceof HeapChoiceGenerator)) { ChoiceGenerator<?> prev_cg = cg.getPreviousChoiceGenerator(); while (!((prev_cg == null) || (prev_cg instanceof HeapChoiceGenerator))) { prev_cg = prev_cg.getPreviousChoiceGenerator(); } cg = prev_cg; } if ((cg instanceof HeapChoiceGenerator) && cg != null) pc = ((HeapChoiceGenerator) cg).getCurrentPCheap(); if (pc != null) System.out.println(env.getStringObject(msgRef) + pc); else System.out.println(env.getStringObject(msgRef) + "HeapPC is null"); }
boolean isRelevantCG(ChoiceGenerator cg) { if (cgClasses == null) { return true; } else { for (Class<?> cls : cgClasses) { if (cls.isAssignableFrom(cg.getClass())) { return true; } } return false; } }
@Override public Instruction execute(SystemState ss, KernelState ks, ThreadInfo ti) { StackFrame sf = ti.getTopFrame(); IntegerExpression sym_v1 = (IntegerExpression) sf.getOperandAttr(1); IntegerExpression sym_v2 = (IntegerExpression) sf.getOperandAttr(0); if ((sym_v1 == null) && (sym_v2 == null)) { // both conditions are concrete // System.out.println("Execute IF_ICMPEQ: The conditions are concrete"); return super.execute(ss, ks, ti); } else { // at least one condition is symbolic ChoiceGenerator<?> cg; if (!ti.isFirstStepInsn()) { // first time around cg = new PCChoiceGenerator(2); ss.setNextChoiceGenerator(cg); return this; } else { // this is what really returns results cg = ss.getChoiceGenerator(); assert (cg instanceof PCChoiceGenerator) : "expected PCChoiceGenerator, got: " + cg; conditionValue = (Integer) cg.getNextChoice() == 0 ? false : true; } int v2 = ti.pop(); int v1 = ti.pop(); // System.out.println("Execute IF_ICMPEQ: "+ conditionValue); PathCondition pc; // pc is updated with the pc stored in the choice generator above // get the path condition from the // previous choice generator of the same type ChoiceGenerator<?> prev_cg = cg.getPreviousChoiceGenerator(); while (!((prev_cg == null) || (prev_cg instanceof PCChoiceGenerator))) { prev_cg = prev_cg.getPreviousChoiceGenerator(); } if (prev_cg == null) pc = new PathCondition(); else pc = ((PCChoiceGenerator) prev_cg).getCurrentPC(); assert pc != null; if (conditionValue) { if (sym_v1 != null) { if (sym_v2 != null) { // both are symbolic values pc._addDet(Comparator.EQ, sym_v1, sym_v2); } else pc._addDet(Comparator.EQ, sym_v1, v2); } else pc._addDet(Comparator.EQ, v1, sym_v2); if (!pc.simplify()) { // not satisfiable ss.setIgnored(true); } else { // pc.solve(); ((PCChoiceGenerator) cg).setCurrentPC(pc); // System.out.println(((PCChoiceGenerator) cg).getCurrentPC()); } return getTarget(); } else { if (sym_v1 != null) { if (sym_v2 != null) { // both are symbolic values pc._addDet(Comparator.NE, sym_v1, sym_v2); } else pc._addDet(Comparator.NE, sym_v1, v2); } else pc._addDet(Comparator.NE, v1, sym_v2); if (!pc.simplify()) { // not satisfiable ss.setIgnored(true); } else { // pc.solve(); ((PCChoiceGenerator) cg).setCurrentPC(pc); // System.out.println(((PCChoiceGenerator) cg).getCurrentPC()); } return getNext(ti); } } }
public static void makeFieldsSymbolic(MJIEnv env, int objRef, int stringRef, int objvRef) { // makes all the fields of obj v symbolic and adds obj v to the symbolic heap to kick off lazy // initialization if (objvRef == -1) throw new RuntimeException("## Error: null object"); // introduce a heap choice generator for the element in the heap ThreadInfo ti = env.getVM().getCurrentThread(); SystemState ss = env.getVM().getSystemState(); ChoiceGenerator<?> cg; if (!ti.isFirstStepInsn()) { cg = new HeapChoiceGenerator(1); // new ss.setNextChoiceGenerator(cg); env.repeatInvocation(); return; // not used anyways } // else this is what really returns results cg = ss.getChoiceGenerator(); assert (cg instanceof HeapChoiceGenerator) : "expected HeapChoiceGenerator, got: " + cg; // see if there were more inputs added before ChoiceGenerator<?> prevHeapCG = cg.getPreviousChoiceGenerator(); while (!((prevHeapCG == null) || (prevHeapCG instanceof HeapChoiceGenerator))) { prevHeapCG = prevHeapCG.getPreviousChoiceGenerator(); } PathCondition pcHeap; SymbolicInputHeap symInputHeap; if (prevHeapCG == null) { pcHeap = new PathCondition(); symInputHeap = new SymbolicInputHeap(); } else { pcHeap = ((HeapChoiceGenerator) prevHeapCG).getCurrentPCheap(); symInputHeap = ((HeapChoiceGenerator) prevHeapCG).getCurrentSymInputHeap(); } // set all the fields to be symbolic ClassInfo ci = env.getClassInfo(objvRef); FieldInfo[] fields = ci.getDeclaredInstanceFields(); FieldInfo[] staticFields = ci.getDeclaredStaticFields(); String name = env.getStringObject(stringRef); String refChain = name + "[" + objvRef + "]"; // why is the type used here? should use the name of the field instead SymbolicInteger newSymRef = new SymbolicInteger(refChain); // ElementInfo eiRef = DynamicArea.getHeap().get(objvRef); ElementInfo eiRef = JVM.getVM().getHeap().get(objvRef); Helper.initializeInstanceFields(fields, eiRef, refChain); Helper.initializeStaticFields(staticFields, ci, ti); // create new HeapNode based on above info // update associated symbolic input heap ClassInfo typeClassInfo = eiRef.getClassInfo(); HeapNode n = new HeapNode(objvRef, typeClassInfo, newSymRef); symInputHeap._add(n); pcHeap._addDet(Comparator.NE, newSymRef, new IntegerConstant(-1)); ((HeapChoiceGenerator) cg).setCurrentPCheap(pcHeap); ((HeapChoiceGenerator) cg).setCurrentSymInputHeap(symInputHeap); // System.out.println(">>>>>>>>>>>> initial pcHeap: " + pcHeap.toString()); return; }