/** * Traverse the statements in the given body, looking for aggregation possibilities; that is, * given a def d and a use u, d has no other uses, u has no other defs, collapse d and u. * * <p>option: only-stack-locals; if this is true, only aggregate variables starting with $ */ protected void internalTransform(Body b, String phaseName, Map<String, String> options) { StmtBody body = (StmtBody) b; boolean onlyStackVars = PhaseOptions.getBoolean(options, "only-stack-locals"); int aggregateCount = 1; if (Options.v().time()) Timers.v().aggregationTimer.start(); boolean changed = false; Map<ValueBox, Zone> boxToZone = new HashMap<ValueBox, Zone>(body.getUnits().size() * 2 + 1, 0.7f); // Determine the zone of every box { Zonation zonation = new Zonation(body); for (Unit u : body.getUnits()) { Zone zone = zonation.getZoneOf(u); for (ValueBox box : u.getUseBoxes()) { boxToZone.put(box, zone); } for (ValueBox box : u.getDefBoxes()) { boxToZone.put(box, zone); } } } do { if (Options.v().verbose()) G.v() .out .println( "[" + body.getMethod().getName() + "] Aggregating iteration " + aggregateCount + "..."); // body.printTo(new java.io.PrintWriter(G.v().out, true)); changed = internalAggregate(body, boxToZone, onlyStackVars); aggregateCount++; } while (changed); if (Options.v().time()) Timers.v().aggregationTimer.end(); }
protected void print_cfg(Body body) { DirectedGraph<Unit> graph = graphtype.buildGraph(body); DotGraph canvas = graphtype.drawGraph(drawer, graph, body); String methodname = body.getMethod().getSubSignature(); String filename = soot.SourceLocator.v().getOutputDir(); if (filename.length() > 0) { filename = filename + java.io.File.separator; } filename = filename + methodname.replace(java.io.File.separatorChar, '.') + DotGraph.DOT_EXTENSION; G.v().out.println("Generate dot file in " + filename); canvas.plot(filename); }
private static void usage() { G.v() .out .println( "Usage:\n" + " java soot.util.CFGViewer [soot options] [CFGViewer options] [class[:method]]...\n\n" + " CFGViewer options:\n" + " (When specifying the value for an '=' option, you only\n" + " need to type enough characters to specify the choice\n" + " unambiguously, and case is ignored.)\n" + "\n" + " --alt-classpath PATH :\n" + " specifies the classpath from which to load classes\n" + " that implement graph types whose names begin with 'Alt'.\n" + " --graph={" + CFGGraphType.help(0, 70, " ".length()) + "} :\n" + " show the specified type of graph.\n" + " Defaults to " + defaultGraph + ".\n" + " --ir={" + CFGIntermediateRep.help(0, 70, " ".length()) + "} :\n" + " create the CFG from the specified intermediate\n" + " representation. Defaults to " + defaultIR + ".\n" + " --brief :\n" + " label nodes with the unit or block index,\n" + " instead of the text of their statements.\n" + " --multipages :\n" + " produce dot file output for multiple 8.5x11\" pages.\n" + " By default, a single page is produced.\n" + " --help :\n" + " print this message.\n" + "\n" + " Particularly relevant soot options (see \"soot --help\" for details):\n" + " --soot-class-path PATH\n" + " --show-exception-dests\n" + " --throw-analysis {pedantic|unit}\n" + " --omit-excepting-unit-edges\n" + " --trim-cfgs\n"); }
/** * Computes the analysis given a UnitGraph computed from a method body. It is recommended that a * ExceptionalUnitGraph (or similar) be provided for correct results in the case of exceptional * control flow. * * @param g a graph on which to compute the analysis. * @see ExceptionalUnitGraph */ public SimpleLiveLocals(UnitGraph graph) { if (Options.v().time()) Timers.v().liveTimer.start(); if (Options.v().verbose()) G.v() .out .println( "[" + graph.getBody().getMethod().getName() + "] Constructing SimpleLiveLocals..."); SimpleLiveLocalsAnalysis analysis = new SimpleLiveLocalsAnalysis(graph); if (Options.v().time()) Timers.v().livePostTimer.start(); // Build unitToLocals map { unitToLocalsAfter = new HashMap<Unit, List>(graph.size() * 2 + 1, 0.7f); unitToLocalsBefore = new HashMap<Unit, List>(graph.size() * 2 + 1, 0.7f); Iterator unitIt = graph.iterator(); while (unitIt.hasNext()) { Unit s = (Unit) unitIt.next(); FlowSet set = (FlowSet) analysis.getFlowBefore(s); unitToLocalsBefore.put(s, Collections.unmodifiableList(set.toList())); set = (FlowSet) analysis.getFlowAfter(s); unitToLocalsAfter.put(s, Collections.unmodifiableList(set.toList())); } } if (Options.v().time()) Timers.v().livePostTimer.end(); if (Options.v().time()) Timers.v().liveTimer.end(); }
/** * This method pushes all newExpr down to be the stmt directly before every invoke of the init * only if they are in the types list */ public void internalTransform(Body b, String phaseName, Map options) { JimpleBody body = (JimpleBody) b; if (Options.v().verbose()) G.v().out.println("[" + body.getMethod().getName() + "] Folding Jimple constructors..."); Chain units = body.getUnits(); List<Unit> stmtList = new ArrayList<Unit>(); stmtList.addAll(units); Iterator<Unit> it = stmtList.iterator(); Iterator<Unit> nextStmtIt = stmtList.iterator(); // start ahead one nextStmtIt.next(); SmartLocalDefs localDefs = SmartLocalDefsPool.v().getSmartLocalDefsFor(body); UnitGraph graph = localDefs.getGraph(); LocalUses localUses = new SimpleLocalUses(graph, localDefs); /* fold in NewExpr's with specialinvoke's */ while (it.hasNext()) { Stmt s = (Stmt) it.next(); if (!(s instanceof AssignStmt)) continue; /* this should be generalized to ArrayRefs */ // only deal with stmts that are an local = newExpr Value lhs = ((AssignStmt) s).getLeftOp(); if (!(lhs instanceof Local)) continue; Value rhs = ((AssignStmt) s).getRightOp(); if (!(rhs instanceof NewExpr)) continue; // check if very next statement is invoke --> // this indicates there is no control flow between // new and invoke and should do nothing if (nextStmtIt.hasNext()) { Stmt next = (Stmt) nextStmtIt.next(); if (next instanceof InvokeStmt) { InvokeStmt invoke = (InvokeStmt) next; if (invoke.getInvokeExpr() instanceof SpecialInvokeExpr) { SpecialInvokeExpr invokeExpr = (SpecialInvokeExpr) invoke.getInvokeExpr(); if (invokeExpr.getBase() == lhs) { break; } } } } // check if new is in the types list - only process these if (!types.contains(((NewExpr) rhs).getType())) continue; List lu = localUses.getUsesOf(s); Iterator luIter = lu.iterator(); boolean MadeNewInvokeExpr = false; while (luIter.hasNext()) { Unit use = ((UnitValueBoxPair) (luIter.next())).unit; if (!(use instanceof InvokeStmt)) continue; InvokeStmt is = (InvokeStmt) use; if (!(is.getInvokeExpr() instanceof SpecialInvokeExpr) || lhs != ((SpecialInvokeExpr) is.getInvokeExpr()).getBase()) continue; // make a new one here AssignStmt constructStmt = Jimple.v() .newAssignStmt(((DefinitionStmt) s).getLeftOp(), ((DefinitionStmt) s).getRightOp()); constructStmt.setRightOp(Jimple.v().newNewExpr(((NewExpr) rhs).getBaseType())); MadeNewInvokeExpr = true; // redirect jumps use.redirectJumpsToThisTo(constructStmt); // insert new one here units.insertBefore(constructStmt, use); constructStmt.addTag(s.getTag("SourceLnPosTag")); } if (MadeNewInvokeExpr) { units.remove(s); } } }
public static Printer v() { return G.v().soot_Printer(); }
public static Aggregator v() { return G.v().soot_jimple_toolkits_base_Aggregator(); }