private boolean defines(Unit curr, String temp_name) { List<ValueBox> boxes = curr.getDefBoxes(); for (ValueBox box : boxes) { String value = box.getValue().toString(); if (value.equals(temp_name)) { return true; } } return false; }
public List getUseBoxes() { // we do not include the bootstrap-method arguments here because they are static arguments List list = new ArrayList(); for (ValueBox element : argBoxes) { list.addAll(element.getValue().getUseBoxes()); list.add(element); } return list; }
public boolean staticFieldRefRedefined(StaticFieldRef lSFieldRef, List<ValueBox> rUseBoxes) { for (ValueBox rUseBox : rUseBoxes) { Value rBoxValue = rUseBox.getValue(); if (rBoxValue instanceof StaticFieldRef) { StaticFieldRef rSFieldRef = (StaticFieldRef) rBoxValue; if (lSFieldRef.getField().equals(rSFieldRef.getField())) { return true; } } } return false; }
public void toString(UnitPrinter up) { up.literal("new"); up.literal(" "); up.type(getBaseType().baseType); for (ValueBox element : sizeBoxes) { up.literal("["); element.toString(up); up.literal("]"); } for (int i = getSizeCount(); i < getBaseType().numDimensions; i++) up.literal("[]"); }
public boolean arrayRefRedefined(ArrayRef lARef, List<ValueBox> rUseBoxes) { for (ValueBox rUseBox : rUseBoxes) { Value rBoxValue = rUseBox.getValue(); if (rBoxValue instanceof ArrayRef) { ArrayRef rARef = (ArrayRef) rBoxValue; if (twoValueEquals(lARef.getBase(), rARef.getBase()) && twoValueEquals(lARef.getIndex(), rARef.getIndex())) { return true; } } } return false; }
public boolean instanceFieldRefRedefined(InstanceFieldRef lIFieldRef, List<ValueBox> rUseBoxes) { for (ValueBox rUseBox : rUseBoxes) { Value rBoxValue = rUseBox.getValue(); if (rBoxValue instanceof InstanceFieldRef) { InstanceFieldRef rIFieldRef = (InstanceFieldRef) rBoxValue; if (twoValueEquals(lIFieldRef.getBase(), rIFieldRef.getBase()) && lIFieldRef.getField().equals(rIFieldRef.getField())) { return true; } } } return false; }
public boolean localRedefined(Local lLocal, List<ValueBox> rUseBoxes) { for (ValueBox rUseBox : rUseBoxes) { Value rBoxValue = rUseBox.getValue(); if (rBoxValue instanceof Local) { Local rLocal = (Local) rBoxValue; if (lLocal.getName().equals(rLocal.getName()) && lLocal.getType().toString().equals(rLocal.getType().toString())) { return true; } } } return false; }
private void analyzeMethod(SootMethod method) { if (!method.hasActiveBody()) { return; } Body activeBody = method.getActiveBody(); List<ValueBox> useAndDefBoxes = activeBody.getUseAndDefBoxes(); for (ValueBox valueBox : useAndDefBoxes) { Value value = valueBox.getValue(); if (value instanceof FieldRef) { analyzeField(method, value); } else if (value instanceof Local) { analyzeLocal(method, value); } } }
public List getUseBoxes() { List useBoxes = new ArrayList(); useBoxes.addAll(opBox.getValue().getUseBoxes()); useBoxes.add(opBox); return useBoxes; }
@SuppressWarnings({"unchecked", "rawtypes"}) private Set<SootField> collectBlockField(JavaCriticalSection cs) { Set result = new HashSet(); int startLine = cs.getStartLine(); int endLine = cs.getEndline(); Body body = cs.getSootMethod().getActiveBody(); PatchingChain<Unit> units = body.getUnits(); for (Unit u : units) { Stmt s = (Stmt) u; LineNumberTag linetag = (LineNumberTag) s.getTag("LineNumberTag"); if (linetag == null) continue; int line = linetag.getLineNumber(); if (line < startLine || line > endLine) { continue; } List<ValueBox> Fieldslist = u.getUseBoxes(); Fieldslist.addAll(u.getDefBoxes()); for (ValueBox box : Fieldslist) { Value v = box.getValue(); if (v instanceof JInstanceFieldRef) { result.add(((JInstanceFieldRef) v).getField()); } } if (s.containsInvokeExpr()) { // ç”¨è°ƒç”¨å›¾èŽ·å¾—è°ƒç”¨ç›®æ ‡ Callees callees = new Callees(getCallGragh(), u); for (SootMethod invokeMethod : callees.explicits()) { if (invokeMethod == null) continue; Collection use = scaner.getUseInstanceFields(invokeMethod); Collection mod = new HashSet(); if (needMod) { mod.addAll(scaner.getModInstanceFields(invokeMethod)); } if (use != null) result.addAll(use); result.addAll(mod); } } } return result; }
public static List<Value> getAllImmediateValue(Stmt stmt) { List<Value> rtVal = new ArrayList<Value>(); List<ValueBox> vbs = stmt.getUseAndDefBoxes(); Set<String> frs = new HashSet<String>(); for (ValueBox vb : vbs) { Value v = vb.getValue(); if (v instanceof FieldRef) { int endPos = v.toString().indexOf('.'); String name = v.toString().substring(0, endPos); frs.add(name); Value existV = null; for (ValueBox vBox : vbs) { if (name.equals(vBox.getValue().toString())) { existV = vBox.getValue(); break; } } if (null != existV) { rtVal.remove(existV); } rtVal.add(v); } if (v instanceof Immediate) { if (!frs.contains(v.toString())) { rtVal.add(v); } } } return rtVal; }
public boolean equivTo(Object o) { if (o instanceof JDynamicInvokeExpr) { JDynamicInvokeExpr ie = (JDynamicInvokeExpr) o; if (!(getMethod().equals(ie.getMethod()) && bsmArgBoxes.length == ie.bsmArgBoxes.length)) return false; int i = 0; for (ValueBox element : bsmArgBoxes) { if (!(element.getValue().equivTo(ie.getBootstrapArg(i)))) return false; i++; } if (!(getMethod().equals(ie.getMethod()) && argBoxes.length == ie.argBoxes.length)) return false; i = 0; for (ValueBox element : argBoxes) { if (!(element.getValue().equivTo(ie.getArg(i)))) return false; i++; } if (!methodRef.equals(ie.methodRef)) return false; if (!bsmRef.equals(ie.bsmRef)) return false; return true; } return false; }
private void visit(SootMethod method) { SootClass soot_class = method.getDeclaringClass(); if (m_classRemapping.containsKey(soot_class.getName())) { return; } if (method.isConcrete() == false) { return; } Body body = method.retrieveActiveBody(); if (body == null) return; m_currMethod = method; fixArguments(method); Iterator<Unit> iter = body.getUnits().iterator(); while (iter.hasNext()) { Unit curr = iter.next(); List<ValueBox> boxes = curr.getUseAndDefBoxes(); for (ValueBox box : boxes) { Value value = box.getValue(); value = mutate(value); box.setValue(value); } } }
public void toString(UnitPrinter up) { label_toString(up); up.literal("switch"); up.literal(" "); up.literal("("); keyBox.toString(up); up.literal(")"); up.newline(); up.literal("{"); up.newline(); Iterator<Object> it = indexList.iterator(); while (it.hasNext()) { Object index = it.next(); up.incIndent(); if (index instanceof String) up.literal("default"); else { up.literal("case"); up.literal(" "); up.literal(index.toString()); } up.literal(":"); up.newline(); List<Object> subBody = index2BodyList.get(index); if (subBody != null) { up.incIndent(); body_toString(up, subBody); if (it.hasNext()) up.newline(); up.decIndent(); } up.decIndent(); } up.literal("}"); up.newline(); }
public FaintVariableAnalysis(Body body) { Chain<Local> locals = body.getLocals(); allVariables = new CollectionFlowUniverse<Local>(locals); universalSet = new ArrayPackedSet(allVariables); for (Local l : locals) universalSet.add(l); useSetMap = new HashMap<Unit, BoundedFlowSet>(); defSetMap = new HashMap<Unit, BoundedFlowSet>(); UnitGraph graph = new BriefUnitGraph(body); for (Unit u : graph) { BoundedFlowSet defSet = new ArrayPackedSet(allVariables); BoundedFlowSet useSet = new ArrayPackedSet(allVariables); for (ValueBox v : u.getDefBoxes()) { // Only do this for locals. We're not going to even try to handle anything // other than locals. if (v.getValue() instanceof Local) { defSet.add(v.getValue()); } } for (ValueBox v : u.getUseBoxes()) { // Only do this for locals. We're not going to even try to handle anything // other than locals. if (v.getValue() instanceof Local) { useSet.add(v.getValue()); } } defSetMap.put(u, defSet); useSetMap.put(u, useSet); } }
public Value getOp() { return opBox.getValue(); }
private Map<Pair<Unit, Set<String>>, Set<Unit>> createProvidesConfigMap( Collection<Unit> unitsInSelection, LiftedReachingDefinitions reachingDefinitions, Body body) { Map<Pair<Unit, Set<String>>, Set<Unit>> unitConfigurationMap = new HashMap<Pair<Unit, Set<String>>, Set<Unit>>(); for (Unit unitFromSelection : unitsInSelection) { if (unitFromSelection instanceof DefinitionStmt) { /* * exclude definitions when it's $temp on the leftOp. */ DefinitionStmt definition = (DefinitionStmt) unitFromSelection; Local leftOp = (Local) definition.getLeftOp(); if (leftOp.getName().charAt(0) == '$') { continue; } System.out.println("Definition:" + definition); // for every unit in the body... Iterator<Unit> iterator = body.getUnits().snapshotIterator(); while (iterator.hasNext()) { Unit nextUnit = iterator.next(); LiftedFlowSet<Collection<Set<Object>>> liftedFlowAfter = reachingDefinitions.getFlowAfter(nextUnit); Set<String>[] configurations = liftedFlowAfter.getConfigurations(); FlowSet[] lattices = liftedFlowAfter.getLattices(); // and for every configuration... for (int configurationIndex = 0; configurationIndex < configurations.length; configurationIndex++) { FlowSet flowSet = lattices[configurationIndex]; Set<String> currConfiguration = configurations[configurationIndex]; FeatureTag nextUnitTag = (FeatureTag) nextUnit.getTag("FeatureTag"); // if the unit belongs to the current configuration... if (nextUnitTag.belongsToConfiguration(currConfiguration)) { // if the definition reaches this unit... if (flowSet.contains(definition)) { List<ValueBox> useBoxes = nextUnit.getUseBoxes(); for (ValueBox vbox : useBoxes) { /* * and the definition is used, add to the * map... */ if (vbox.getValue().equivTo(leftOp)) { Pair<Unit, Set<String>> currentPair = new Pair<Unit, Set<String>>(definition, currConfiguration); Set<Unit> unitConfigurationReachesSet = unitConfigurationMap.get(currentPair); if (unitConfigurationReachesSet == null) { unitConfigurationReachesSet = new HashSet<Unit>(); unitConfigurationReachesSet.add(nextUnit); unitConfigurationMap.put(currentPair, unitConfigurationReachesSet); } else { unitConfigurationReachesSet.add(nextUnit); } } } } } } } } } return unitConfigurationMap; }
SimpleLiveLocalsAnalysis(UnitGraph g) { super(g); if (Options.v().time()) Timers.v().liveSetupTimer.start(); emptySet = new ArraySparseSet(); // Create kill sets. { unitToKillSet = new HashMap<Unit, FlowSet>(g.size() * 2 + 1, 0.7f); Iterator unitIt = g.iterator(); while (unitIt.hasNext()) { Unit s = (Unit) unitIt.next(); FlowSet killSet = emptySet.clone(); Iterator boxIt = s.getDefBoxes().iterator(); while (boxIt.hasNext()) { ValueBox box = (ValueBox) boxIt.next(); if (box.getValue() instanceof Local) killSet.add(box.getValue(), killSet); } unitToKillSet.put(s, killSet); } } // Create generate sets { unitToGenerateSet = new HashMap<Unit, FlowSet>(g.size() * 2 + 1, 0.7f); Iterator unitIt = g.iterator(); while (unitIt.hasNext()) { Unit s = (Unit) unitIt.next(); FlowSet genSet = emptySet.clone(); Iterator boxIt = s.getUseBoxes().iterator(); while (boxIt.hasNext()) { ValueBox box = (ValueBox) boxIt.next(); if (box.getValue() instanceof Local) genSet.add(box.getValue(), genSet); } unitToGenerateSet.put(s, genSet); } } if (Options.v().time()) Timers.v().liveSetupTimer.end(); if (Options.v().time()) Timers.v().liveAnalysisTimer.start(); doAnalysis(); if (Options.v().time()) Timers.v().liveAnalysisTimer.end(); }
public String toString() { return "throw " + opBox.getValue().toString(); }
public void toString(UnitPrinter up) { up.literal(Jimple.THROW); up.literal(" "); opBox.toString(up); }
public List getBootstrapArgs() { List l = new ArrayList(); for (ValueBox element : bsmArgBoxes) l.add(element.getValue()); return l; }
public static void main(String[] args) { List<String> argsList = new ArrayList<String>(Arrays.asList(args)); argsList.addAll( Arrays.asList( new String[] { "-w", // "-p", "cg.spark", "on-fly-cg:true", // "-main-class", "testers.CallGraphs",// main-class "testers.CallGraphs", // argument classes // "testers.A" // })); argsList.add("-soot-class-path"); argsList.add( "/home/nnguyen/workspaceluna/CoGConstructor/bin:/usr/java/jdk1.7.0_79/jre/lib/rt.jar:/usr/java/jdk1.7.0_79/jre/lib/jce.jar"); argsList.add("-p"); argsList.add("cg"); argsList.add("all-reachable:true"); argsList.add("-p"); argsList.add("cg.spark"); argsList.add("on-fly-cg:true"); argsList.add("-f"); argsList.add("J"); // argsList.add("-no-bodies-for-excluded"); // argsList.add("pre-jimplify:true"); System.out.println("JB " + PackManager.v().getPack("jb").getDefaultOptions()); System.out.println("JBLS " + PackManager.v().getPhase("jb.ls").getDefaultOptions()); System.out.println("JBDAE " + PackManager.v().getPhase("jb.dae").getDefaultOptions()); System.out.println("CHCHA " + PackManager.v().getPhase("cg.cha").getDeclaredOptions()); System.out.println("CG" + PackManager.v().getPack("cg").getDeclaredOptions()); // PackManager.v().getPack("wjtp").add(new Transform("wjtp.myTrans", new SceneTransformer() { // // System.out.println(PackManager.v().getPhase("cg.spark").getDeclaredOptions()); // // // PackManager.v().getPack("cg").add(new Transform("cg.myTrans", new SceneTransformer() { // // @Override // protected void internalTransform(String phaseName, Map options) { // CHATransformer.v().transform(); // SootClass a = Scene.v().getSootClass("testers.A"); // // SootMethod src = Scene.v().getMainClass().getMethodByName("doStuff"); // CallGraph cg = Scene.v().getCallGraph(); // // Iterator<MethodOrMethodContext> targets = new Targets(cg.edgesOutOf(src)); // // while (targets.hasNext()) { // SootMethod tgt = (SootMethod) targets.next(); // System.out.println(src + " may call " + tgt); // } // // Iterator<MethodOrMethodContext> sources = new Sources(cg.edgesInto(src)); // // while (sources.hasNext()) { // SootMethod tgt = (SootMethod) sources.next(); // // System.out.println(src + " may be called by " + tgt + " " + tgt.getName()); // } // // } // // })); args = argsList.toArray(new String[0]); Options.v().parse(args); // disable if want to use soot.Main.main Options.v().set_keep_line_number(true); Options.v().set_whole_program(true); Options.v().set_allow_phantom_refs(true); Options.v().setPhaseOption("jb", "use-original-names:true"); // soot.Main.main(args); List addedEntryPoints = new ArrayList(); // for (String ePoint : customEntryPoints) { SootClass c = Scene.v().forceResolve("testers.CallGraphs", SootClass.BODIES); c.setApplicationClass(); Scene.v().loadNecessaryClasses(); SootMethod method; String methodName = "main"; if (!methodName.contains("(")) { method = c.getMethodByName(methodName); System.out.println("FOUND IT"); } else { // List<Type> types = new ArrayList<Type>(); method = c.getMethod(methodName); System.out.println("FOUND IT"); } addedEntryPoints.add(method); // } Scene.v().setEntryPoints(addedEntryPoints); PackManager.v().runPacks(); JimpleBasedInterproceduralCFG icfg = new JimpleBasedInterproceduralCFG(); IFDSTabulationProblem< Unit, Pair<Value, Set<DefinitionStmt>>, SootMethod, InterproceduralCFG<Unit, SootMethod>> problem = (IFDSTabulationProblem) new IFDSReachingDefinitions(icfg); System.out.println("Number of threads :" + problem.numThreads()); JimpleIFDSSolver<Pair<Value, Set<DefinitionStmt>>, InterproceduralCFG<Unit, SootMethod>> solver = new JimpleIFDSSolver< Pair<Value, Set<DefinitionStmt>>, InterproceduralCFG<Unit, SootMethod>>( problem, true); System.out.println("Started Solving...."); System.out.println(Scene.v().getMainMethod().getName()); SootMethod mMethod = Scene.v().getSootClass("testers.CallGraphs").getMethodByName("main"); // SootMethod mMethod = Scene.v().getMainClass().getMethodByName("doStuff2"); BiDirICFGFactory icfgFactory = new DefaultBiDiICFGFactory(); IInfoflowCFG iCfg = icfgFactory.buildBiDirICFG(CallgraphAlgorithm.AutomaticSelection, true); CallGraph cg = Scene.v().getCallGraph(); // SootClass cl = Scene.v().getMainClass(); for (SootClass cl : Scene.v().getClasses()) { for (SootMethod sm : cl.getMethods()) { if (sm.getSignature().contains("testers") || sm.getSignature().contains("java.lang.Object next()")) { // if // (sm.getSignature().equals("<testers.CallGraphs$CellIterator: java.lang.Object // next()>")) // { // if (sm.getSignature().equals("<testers.CallGraphs: void p4(int)>")) { System.out.println( "WE FOUND " + sm.getSignature() + " AT " + sm.getJavaSourceStartLineNumber()); Iterator sources = new Sources(cg.edgesInto(sm)); while (sources.hasNext()) { SootMethod sm2 = (SootMethod) sources.next(); System.out.println("CALLED BY " + sm2.getSignature()); } // sources = new Sources(cg.edgesOutOf(sm)); // while (sources.hasNext()) { // SootMethod sm2 = (SootMethod) sources.next(); // System.out.println("CALLS " + sm2.getSignature()); // } // } } } } if (mMethod.hasActiveBody()) { System.out.println("YESSSSSSSSSSSSSSSSS"); Body b = mMethod.getActiveBody(); for (Unit u : b.getUnits()) { System.out.println(u + " AT " + u.getJavaSourceStartLineNumber()); } System.out.println("==================="); for (Unit u : b.getUnits()) { if (u instanceof IfStmt) { System.out.println("IF STMT AT " + u.getJavaSourceStartLineNumber()); IfStmt stmt = (IfStmt) u; System.out.println(u); Value condition = stmt.getCondition(); ValueBox conditionBox = stmt.getConditionBox(); System.out.println( "Condition " + condition + " AT " + conditionBox.getJavaSourceStartLineNumber()); System.out.println( "Target " + stmt.getTarget() + " AT " + stmt.getTarget().getJavaSourceStartLineNumber()); System.out.println( iCfg.getPostdominatorOf(u) + " AT " + u.getJavaSourceStartLineNumber()); System.out.println(iCfg.getSuccsOf(u)); System.out.println("====="); } if (u instanceof GotoStmt) { System.out.println("GOTO STMT AT " + u.getJavaSourceStartLineNumber()); GotoStmt stmt = (GotoStmt) u; System.out.println(u); System.out.println(stmt.getTarget()); System.out.println("====="); } } } // commented to test the IfStmt // if (!Scene.v().getMainMethod().hasActiveBody()) { // System.out.println("NONOOOOOOOOOOOOOOOOOOOOOOOOOOO"); // } // // Scene.v().getMainMethod().getActiveBody() // solver.solve(); // System.out.println("Completed Solving...."); // solver.dumpResults(); }
private static String finegrainedFlowResults() { int totalReachableIfs = 0; int taintedReachableIfs = 0; int totalCountOfTaintSets = 0; int totalSizeOfTaintSets = 0; long totalValues = 0; Set<InfoValue> allSrcs = new HashSet<InfoValue>(); Set<Set<InfoValue>> allSrcSets = new HashSet<Set<InfoValue>>(); StringBuffer buf = new StringBuffer(); for (MethodOrMethodContext momc : PTABridge.v().getReachableMethodContexts()) { // reset counted locals for each method Set<Value> countedLocals = new HashSet<Value>(); SootMethod method = momc.method(); if (!method.isConcrete()) continue; try { Body body = method.retrieveActiveBody(); Iterator<Unit> unitIt = body.getUnits().snapshotIterator(); while (unitIt.hasNext()) { Stmt stmt = (Stmt) unitIt.next(); for (ValueBox vb : stmt.getUseAndDefBoxes()) { Value v = vb.getValue(); if (countedLocals.contains(v)) continue; countedLocals.add(v); Set<InfoValue> taints = getTaintSet(v, momc); if (taints != null) totalValues++; if (taints != null && !taints.isEmpty()) { allSrcs.addAll(taints); totalCountOfTaintSets++; totalSizeOfTaintSets += taints.size(); if (!allSrcSets.contains(taints)) allSrcSets.add(taints); countedLocals.add(v); } } if (stmt instanceof IfStmt) { totalReachableIfs++; boolean hasTainted = false; for (ValueBox vb : stmt.getUseBoxes()) { Value v = vb.getValue(); Set<InfoValue> taints = getTaintSet(v, momc); if (taints != null && !taints.isEmpty()) { hasTainted = true; break; } } totalReachableIfs++; if (hasTainted) { taintedReachableIfs++; } } } } catch (Exception e) { // ignore and continue } } buf.append("Tainted Reachable if statements: " + taintedReachableIfs + "\n"); buf.append("Total Reachable if Statements: " + totalReachableIfs + "\n"); buf.append( "Count of non-zero taint sets for primitives and strings: " + totalCountOfTaintSets + "\n"); buf.append( "Total distinct reachable primitives or string values in code: " + totalValues + "\n"); buf.append( "Total size of non-zero taint sets for primitives and strings: " + totalSizeOfTaintSets + "\n"); buf.append("Count of distinct sources: " + allSrcs.size() + "\n"); buf.append("Total distinct source sets: " + allSrcSets.size() + "\n"); return buf.toString(); }
public void setOp(Value op) { opBox.setValue(op); }
public Value get_Key() { return keyBox.getValue(); }
private static boolean internalAggregate( StmtBody body, Map<ValueBox, Zone> boxToZone, boolean onlyStackVars) { LocalUses localUses; LocalDefs localDefs; ExceptionalUnitGraph graph; boolean hadAggregation = false; Chain<Unit> units = body.getUnits(); graph = new ExceptionalUnitGraph(body); localDefs = new SmartLocalDefs(graph, new SimpleLiveLocals(graph)); localUses = new SimpleLocalUses(graph, localDefs); List<Unit> unitList = new PseudoTopologicalOrderer<Unit>().newList(graph, false); for (Unit u : unitList) { if (!(u instanceof AssignStmt)) continue; AssignStmt s = (AssignStmt) u; Value lhs = s.getLeftOp(); if (!(lhs instanceof Local)) continue; Local lhsLocal = (Local) lhs; if (onlyStackVars && !lhsLocal.getName().startsWith("$")) continue; List<UnitValueBoxPair> lu = localUses.getUsesOf(s); if (lu.size() != 1) continue; UnitValueBoxPair usepair = lu.get(0); Unit use = usepair.unit; ValueBox useBox = usepair.valueBox; List<Unit> ld = localDefs.getDefsOfAt(lhsLocal, use); if (ld.size() != 1) continue; // Check to make sure aggregation pair in the same zone if (boxToZone.get(s.getRightOpBox()) != boxToZone.get(usepair.valueBox)) { continue; } /* we need to check the path between def and use */ /* to see if there are any intervening re-defs of RHS */ /* in fact, we should check that this path is unique. */ /* if the RHS uses only locals, then we know what to do; if RHS has a method invocation f(a, b, c) or field access, we must ban field writes, other method calls and (as usual) writes to a, b, c. */ boolean cantAggr = false; boolean propagatingInvokeExpr = false; boolean propagatingFieldRef = false; boolean propagatingArrayRef = false; ArrayList<FieldRef> fieldRefList = new ArrayList<FieldRef>(); LinkedList<Value> localsUsed = new LinkedList<Value>(); for (ValueBox vb : s.getUseBoxes()) { Value v = vb.getValue(); if (v instanceof Local) localsUsed.add(v); else if (v instanceof InvokeExpr) propagatingInvokeExpr = true; else if (v instanceof ArrayRef) propagatingArrayRef = true; else if (v instanceof FieldRef) { propagatingFieldRef = true; fieldRefList.add((FieldRef) v); } } // look for a path from s to use in graph. // only look in an extended basic block, though. List<Unit> path = graph.getExtendedBasicBlockPathBetween(s, use); if (path == null) continue; Iterator<Unit> pathIt = path.iterator(); // skip s. if (pathIt.hasNext()) pathIt.next(); while (pathIt.hasNext() && !cantAggr) { Stmt between = (Stmt) (pathIt.next()); if (between != use) { // Check for killing definitions for (ValueBox vb : between.getDefBoxes()) { Value v = vb.getValue(); if (localsUsed.contains(v)) { cantAggr = true; break; } if (propagatingInvokeExpr || propagatingFieldRef || propagatingArrayRef) { if (v instanceof FieldRef) { if (propagatingInvokeExpr) { cantAggr = true; break; } else if (propagatingFieldRef) { // Can't aggregate a field access if passing a definition of a field // with the same name, because they might be aliased for (FieldRef fieldRef : fieldRefList) { if (((FieldRef) v).getField() == fieldRef.getField()) { cantAggr = true; break; } } } } else if (v instanceof ArrayRef) { if (propagatingInvokeExpr) { // Cannot aggregate an invoke expr past an array write cantAggr = true; break; } else if (propagatingArrayRef) { // cannot aggregate an array read past a write // this is somewhat conservative // (if types differ they may not be aliased) cantAggr = true; break; } } } } // Make sure not propagating past a {enter,exit}Monitor if (propagatingInvokeExpr && between instanceof MonitorStmt) cantAggr = true; } // Check for intervening side effects due to method calls if (propagatingInvokeExpr || propagatingFieldRef || propagatingArrayRef) { for (final ValueBox box : between.getUseBoxes()) { if (between == use && box == useBox) { // Reached use point, stop looking for // side effects break; } Value v = box.getValue(); if (v instanceof InvokeExpr || (propagatingInvokeExpr && (v instanceof FieldRef || v instanceof ArrayRef))) { cantAggr = true; break; } } } } // we give up: can't aggregate. if (cantAggr) { continue; } /* assuming that the d-u chains are correct, */ /* we need not check the actual contents of ld */ Value aggregatee = s.getRightOp(); if (usepair.valueBox.canContainValue(aggregatee)) { boolean wasSimpleCopy = isSimpleCopy(usepair.unit); usepair.valueBox.setValue(aggregatee); units.remove(s); hadAggregation = true; // clean up the tags. If s was not a simple copy, the new statement should get // the tags of s. // OK, this fix was wrong. The condition should not be // "If s was not a simple copy", but rather "If usepair.unit // was a simple copy". This way, when there's a load of a constant // followed by an invoke, the invoke gets the tags. if (wasSimpleCopy) { // usepair.unit.removeAllTags(); usepair.unit.addAllTagsOf(s); } } else { /* if(Options.v().verbose()) { G.v().out.println("[debug] failed aggregation"); G.v().out.println("[debug] tried to put "+aggregatee+ " into "+usepair.stmt + ": in particular, "+usepair.valueBox); G.v().out.println("[debug] aggregatee instanceof Expr: " +(aggregatee instanceof Expr)); }*/ } } return hadAggregation; }