package cute.instrument; import soot.*; import soot.jimple.*; import soot.util.Chain; import java.util.List; /** * . * User: Koushik Sen (ksen@cs.uiuc.edu) * Date: Nov 7, 2005 * Time: 5:41:17 PM */ public class ParseExpr { /** * Instruments the expression v contained in s. * <p> * If v = x, then instrumentation results in<br> * {@link cute.concolic.Call#loadAddress(int, int, int)} loadAddress(0,st.get(x),lineNo);}<br> * loadValue(x, lineNo);<br> * s; * <p> * If v = o.x and , then instrumentation results in<br> * {@link cute.concolic.Call#loadAddress(Object, int, int)} loadAddress(o,st.get(x),lineNo);}<br> * loadValue(o.x, lineNo);<br> * s; * * @param b * @param v * @param units * @param s * @param st * @param isConcurrent * @param lineNo * @param isCond */ public static void instrument(Body b,Value v,Value left,Chain units,Stmt s,SymbolTable st, boolean isConcurrent,int lineNo,boolean isCond){ if(v instanceof Local || v instanceof ArrayRef || v instanceof InstanceFieldRef || v instanceof StaticFieldRef){ AddCallWithAddress.instrument(v,units,s,"loadAddress",true,st,lineNo,false); } if(v instanceof Local || v instanceof ArrayRef || v instanceof InstanceFieldRef || v instanceof StaticFieldRef || v instanceof Constant){ AddValue.instrument(b,v,units,s,"loadValue",true,lineNo,isCond); } else if(v instanceof AddExpr || v instanceof SubExpr || v instanceof MulExpr || v instanceof CmpExpr || v instanceof CmpgExpr || v instanceof CmplExpr){ if(!(((BinopExpr)v).getOp1() instanceof Constant && ((BinopExpr)v).getOp2() instanceof Constant)){ ParseExpr.instrument(b,((BinopExpr)v).getOp1(),null,units,s,st,isConcurrent,lineNo,false); ParseExpr.instrument(b,((BinopExpr)v).getOp2(),null,units,s,st,isConcurrent,lineNo,false); SootMethodRef mr = Scene.v().getMethod("<cute.concolic.Call: void applyOp(java.lang.String,int)>").makeRef(); Value sym = StringConstant.v(((BinopExpr)v).getSymbol()); units.insertBefore(Jimple.v().newInvokeStmt(Jimple.v().newStaticInvokeExpr(mr,sym,IntConstant.v(lineNo))),s); } } else if(v instanceof EqExpr || v instanceof LeExpr || v instanceof LtExpr || v instanceof GeExpr || v instanceof GtExpr || v instanceof NeExpr){ if(!(((BinopExpr)v).getOp1() instanceof Constant && ((BinopExpr)v).getOp2() instanceof Constant)){ ParseExpr.instrument(b,((BinopExpr)v).getOp1(),null,units,s,st,isConcurrent,lineNo,true); ParseExpr.instrument(b,((BinopExpr)v).getOp2(),null,units,s,st,isConcurrent,lineNo,true); SootMethodRef mr = Scene.v().getMethod("<cute.concolic.Call: void applyOp(java.lang.String,int)>").makeRef(); Value sym = StringConstant.v(((BinopExpr)v).getSymbol()); units.insertBefore(Jimple.v().newInvokeStmt(Jimple.v().newStaticInvokeExpr(mr,sym,IntConstant.v(lineNo))),s); } } else if(v instanceof NegExpr){ ParseExpr.instrument(b,((NegExpr)v).getOp(),null,units,s,st,isConcurrent,lineNo,false); SootMethodRef mr = Scene.v().getMethod("<cute.concolic.Call: void applyOp(java.lang.String,int)>").makeRef(); Value sym = StringConstant.v("-"); units.insertBefore(Jimple.v().newInvokeStmt(Jimple.v().newStaticInvokeExpr(mr,sym,IntConstant.v(lineNo))),s); } else if(v instanceof CastExpr){ ParseExpr.instrument(b,((CastExpr)v).getOp(),null,units,s,st,isConcurrent,lineNo,false); } else if(v instanceof InvokeExpr){ // popAll() // pushArg(x) where x is local if(isConcurrent){ AddSyncMethodInstr.instrument((InvokeExpr)v,units,b,s,true,"lock",lineNo); } SootMethodRef mr = Scene.v().getMethod("<cute.concolic.Call: void popAll(int)>").makeRef(); units.insertBefore(Jimple.v().newInvokeStmt(Jimple.v().newStaticInvokeExpr(mr,IntConstant.v(lineNo))),s); List args = ((InvokeExpr)v).getArgs(); for (int i=0; i<args.size(); i++) { Value varg = (Value) args.get(args.size()-i-1); AddCallWithAddress.instrument(varg,units,s,"pushArg",true,st,lineNo,true); } if(v instanceof InstanceInvokeExpr){ AddCallWithAddress.instrument(((InstanceInvokeExpr)v).getBase(),units,s,"pushArg",true,st,lineNo,true); } Value msig = StringConstant.v(((InvokeExpr)v).getMethod().getSignature()); System.out.println("Sig:"+msig); mr = Scene.v().getMethod("<cute.concolic.Call: void funBegin(java.lang.String,int)>").makeRef(); units.insertBefore(Jimple.v().newInvokeStmt(Jimple.v().newStaticInvokeExpr(mr,msig,IntConstant.v(lineNo))),s); if(isConcurrent){ AddSyncMethodInstr.instrument((InvokeExpr)v,units,b,s,false,"unlock",lineNo); } if(left!=null){ AddCallWithAddress.instrument(left,units,s,"storeReturn",false,st,lineNo,false); } for (int i=0; i<args.size(); i++) { Value varg = (Value) args.get(i); AddValue.instrument(b,varg,units,s,"pushValue",false,lineNo,true); } if(v instanceof InstanceInvokeExpr){ AddValue.instrument(b,((InstanceInvokeExpr)v).getBase(),units,s,"pushValue",false,lineNo,true); } mr = Scene.v().getMethod("<cute.concolic.Call: void funEnd(int)>").makeRef(); units.insertAfter(Jimple.v().newInvokeStmt(Jimple.v().newStaticInvokeExpr(mr,IntConstant.v(lineNo))),s); } else if(v instanceof NewArrayExpr){ SootMethodRef mr = Scene.v().getMethod("<cute.concolic.Call: void popAll(int)>").makeRef(); units.insertBefore(Jimple.v().newInvokeStmt(Jimple.v().newStaticInvokeExpr(mr,IntConstant.v(lineNo))),s); Value sizeValue = ((NewArrayExpr)v).getSize(); AddCallWithAddress.instrument(sizeValue,units,s,"pushArg",true,st,lineNo,true); if(left!=null) AddCallWithAddress.instrument(left,units,s,"pushArg",true,st,lineNo,true); mr = Scene.v().getMethod("<cute.concolic.Call: void funBegin(java.lang.String,int)>").makeRef(); units.insertBefore(Jimple.v().newInvokeStmt(Jimple.v().newStaticInvokeExpr( mr,StringConstant.v("NewArray"),IntConstant.v(lineNo))),s); AddValue.instrument(b,sizeValue,units,s,"pushValue",false,lineNo,true); if (left != null) AddValue.instrument(b,left,units,s,"pushValue",false,lineNo,true); mr = Scene.v().getMethod("<cute.concolic.Call: void funEnd(int)>").makeRef(); units.insertAfter(Jimple.v().newInvokeStmt(Jimple.v().newStaticInvokeExpr(mr,IntConstant.v(lineNo))),s); } else if(v instanceof LengthExpr){ SootMethodRef mr = Scene.v().getMethod("<cute.concolic.Call: void popAll(int)>").makeRef(); units.insertBefore(Jimple.v().newInvokeStmt(Jimple.v().newStaticInvokeExpr(mr,IntConstant.v(lineNo))),s); Value arg = ((LengthExpr)v).getOp(); AddCallWithAddress.instrument(arg,units,s,"pushArg",true,st,lineNo,true); mr = Scene.v().getMethod("<cute.concolic.Call: void funBegin(java.lang.String,int)>").makeRef(); units.insertBefore(Jimple.v().newInvokeStmt(Jimple.v().newStaticInvokeExpr( mr,StringConstant.v("ArrayLength"),IntConstant.v(lineNo))),s); if(left!=null){ AddCallWithAddress.instrument(left,units,s,"storeReturn",false,st,lineNo,false); } AddValue.instrument(b,arg,units,s,"pushValue",false,lineNo,true); mr = Scene.v().getMethod("<cute.concolic.Call: void funEnd(int)>").makeRef(); units.insertAfter(Jimple.v().newInvokeStmt(Jimple.v().newStaticInvokeExpr(mr,IntConstant.v(lineNo))),s); } } }