package jqian.sootex.location; import java.util.*; import soot.*; import soot.jimple.*; /** * Build a map between actuals and formals(no map on extended aprameters) */ public class Backbinder { /** * @param actualCallee is the actual callee, not the declared callee */ public Backbinder(InvokeInfo invoke,SootMethod actualCallee) { getActualFormalMap(invoke,actualCallee,_afMap); } @SuppressWarnings("unchecked") public static Map<Value,Value> createParmArgMap(Unit invoke,SootMethod callee){ InvokeExpr expr = ((Stmt)invoke).getInvokeExpr(); SootMethod declaredCallee = expr.getMethod(); String signature = declaredCallee.getSubSignature(); String tgtSignature = callee.getSubSignature(); //implicit call if(!signature.equals(tgtSignature)){ return Collections.EMPTY_MAP; } Map<Value,Value> map = new HashMap<Value,Value>(); Body body = callee.getActiveBody(); //map for this if(!callee.isStatic()){ Value thiz = body.getThisLocal(); Value receiver = ((InstanceInvokeExpr)expr).getBase(); map.put(thiz,receiver); map.put(receiver,thiz); } //map for parameters int paramCount = callee.getParameterCount(); for(int i=0;i<paramCount;i++){ Value param = body.getParameterLocal(i); Value arg = expr.getArg(i); map.put(param,arg); map.put(arg,param); } return map; } protected void getActualFormalMap(InvokeInfo invoke, SootMethod actualCallee,Map<Location,Location> out){ String tgtSignature = actualCallee.getSubSignature(); SootMethod declaredCallee = invoke.getDeclaredCallee(); String signature = declaredCallee.getSubSignature(); //implicit call if(!signature.equals(tgtSignature)){ return; } //map for this if(!actualCallee.isStatic()){ Location thisPtr = Location.getThisPointer(actualCallee); Location receiver=invoke.receiver(); out.put(thisPtr,receiver); out.put(receiver,thisPtr); } //map for parameters Location[] args = invoke.getArgLocs(); int argNum = args.length; for(int i=0;i<argNum;i++){ Local p = actualCallee.getActiveBody().getParameterLocal(i); Location param = Location.valueToLocation(p); out.put(param,args[i]); out.put(args[i],param); } //map for return if(actualCallee.getReturnType() instanceof RefLikeType){ Location formalRet = Location.methodToRet(actualCallee); Location actualRet = invoke.getRetLoc(); if (formalRet != null && actualRet != null) { out.put(formalRet, actualRet); out.put(actualRet, formalRet); } } } /** Backbind a parameter based access path to an argument based access path * @return CAN return null if ap is an access path on parameter while the * return value is not used, */ public AccessPath backbind(AccessPath ap) { Location param=ap.getRoot(); //do not perform mapping for globals if(param instanceof GlobalLocation){ return ap; }else{ Location arg = _afMap.get(param); if(arg==null) return null; else return ap.getRootModified(arg); } } public Location backbind(Location param){ return _afMap.get(param); } public void backbindAccessPaths(Collection<AccessPath> aps,Collection<AccessPath> out) { for(Iterator<AccessPath> it=aps.iterator();it.hasNext();){ AccessPath formal = it.next(); AccessPath actual = backbind(formal); if(actual!=null) out.add(actual); } } ////////////////////////////////////////////////////////// private Map<Location,Location> _afMap=new HashMap<Location,Location>(); }