public static Tuple2<CallGraph, PointerAnalysis> getCGnPA(final Setting setting) throws IllegalArgumentException, CancelException, PDGFormatException, IOException, WalaException, InvalidClassFileException { final String main = setting.main(); final String mainClassSimpleName = main.replace('/', '.').replace('$', '.').substring(1); SDGFactory.Config cfg = setting.jsdgConf(); Analyzer.cfg = cfg; IProgressMonitor progress = new VerboseProgressMonitor(System.out); final Result result = getJoanaSDG(cfg, progress); { progress.beginTask("Saving SDG to " + cfg.outputSDGfile, -1); BufferedOutputStream bOut = new BufferedOutputStream(new FileOutputStream(cfg.outputSDGfile)); SDGSerializer.toPDGFormat(result.sdg, bOut); progress.done(); } Util.dumpCallGraph(result.cg, mainClassSimpleName, null); return new Tuple2<CallGraph, PointerAnalysis>(result.cg, result.pts); }
private static void printDetails(CGNode method, ExplodedControlFlowGraph cfg, FlowGraph pruned) { int deletedEdges = 0; int originalEdges = 0; for (IExplodedBasicBlock node : cfg) { originalEdges += cfg.getSuccNodeCount(node); Iterator<IExplodedBasicBlock> it = cfg.getSuccNodes(node); int srcNum = node.getNumber(); while (it.hasNext()) { IExplodedBasicBlock dst = it.next(); int dstNum = dst.getNumber(); if (pruned.hasEdge(srcNum, dstNum)) { deletedEdges++; } } } DecimalFormat df = new DecimalFormat("00.00"); double percent = ((double) deletedEdges / (double) originalEdges) * 100.0; Log.info( "EXC: " + df.format(percent) + "% - edges: " + originalEdges + " deleted: " + deletedEdges + " - " + edu.kit.joana.deprecated.jsdg.util.Util.methodName(method.getMethod())); }
private static void computeAliasVariant( final MoJo mojo, final MayAliasGraph alias, final IMethod method, final boolean ignoreExceptions, final String outDir) throws IllegalArgumentException, CancelException, PDGFormatException, WalaException, FileNotFoundException { final Logger debug = Log.getLogger(Log.L_MOJO_DEBUG); final Logger info = Log.getLogger(Log.L_MOJO_INFO); info.out("Preparing points-to config and call graph..."); final PointsTo pts = MoJo.computePointsTo(alias); if (debug.isEnabled()) { AliasGraphIO.dumpToDot(alias, outDir + ".alias.dot"); } AliasGraphIO.writeOut(alias, new FileOutputStream(outDir + ".alias")); final AnalysisOptions optPts = mojo.createAnalysisOptionsWithPTS(pts, method); final CallGraphResult cg = mojo.computeContextSensitiveCallGraph(optPts); if (debug.isEnabled()) { final PrintStream ssaOut = new PrintStream(outDir + ".ssa.txt"); Util.dumpSSA(cg.cg.getFakeRootNode().getIR(), ssaOut); Util.dumpPhiSSA(cg.cg.getFakeRootNode().getIR(), ssaOut); ssaOut.flush(); ssaOut.close(); Util.dumpHeapGraphToFile( outDir + ".heap.dot", cg.pts.getHeapGraph(), cg.cg.getFakeRootNode().getMethod()); } info.out("done, sdg... "); // run analysis on callgraph with minimal alias configuration // ... final edu.kit.joana.ifc.sdg.graph.SDG sdg = createSDG(cg, optPts, method, ignoreExceptions); SDGSerializer.toPDGFormat(sdg, new BufferedOutputStream(new FileOutputStream(outDir + ".pdg"))); info.out("(" + sdg.edgeSet().size() + " edges)"); if (debug.isEnabled()) { final int summary = outputSummaryEdges(sdg, method.getReference().getSignature(), outDir + ".sum.dot"); debug.out(" (" + summary + " sum)"); } info.outln(" done."); }
public String toString() { if (param != null) { return "cfg: " + param.toString(); } else if (bb != null) { return "cfg: " + Util.prettyBasicBlock(bb); } else if (call != null) { return "cfg: " + call; } else if (artificial != null) { return "cfg: " + artificial; } else { return "cfg: empty"; } }
private void createCFG() { for (IExplodedBasicBlock block : ecfg) { Set<CFGNode> last = lastNodesOfBB(block); Iterator<IExplodedBasicBlock> it = getSuccs(block); while (it.hasNext()) { IExplodedBasicBlock succ = it.next(); if (succ == null) { Log.warn("Basic block is null in " + Util.methodName(ecfg.getMethod())); continue; } Set<CFGNode> firstOfSucc = firstNodesOfBB(succ); for (CFGNode from : last) { for (CFGNode to : firstOfSucc) { cfg.addEdge(from, to); } } } } cfg.addEdge(entry, exit); }
private static Result getOrigSDG(Config cfg, IProgressMonitor progress) throws IllegalArgumentException, CancelException, PDGFormatException, IOException, WalaException, InvalidClassFileException { progress.beginTask(Messages.getString("Analyzer.Task_Prepare_IR"), -1); // $NON-NLS-1$ com.ibm.wala.ipa.callgraph.impl.Util.setNativeSpec(cfg.nativesXML); progress.subTask(Messages.getString("Analyzer.SubTask_Analysis_Scope")); // $NON-NLS-1$ ClassLoader loader = cfg.getClass().getClassLoader(); AnalysisScope scope = Util.makeAnalysisScope(cfg, loader); // AnalysisScopeReader.makeJavaBinaryAnalysisScope(cfg.scopeFile, cfg.classpath, null); progress.done(); ClassHierarchy cha = ClassHierarchy.make(scope, progress); Iterable<Entrypoint> entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, cfg.mainClass); AnalysisOptions options = new AnalysisOptions(scope, entrypoints); AnalysisCache cache = new AnalysisCache(); progress.subTask( Messages.getString("Analyzer.SubTask_Call_Graph_Builder") + cfg.pointsTo); // $NON-NLS-1$ SSAPropagationCallGraphBuilder builder = SDGFactory.getCallGraphBuilder(cfg.pointsTo, options, cache, cha, scope); /** * Change the wala internal pointer and instancekeyfactory of the callgraph builder to our * adapter. So we can keep track of the created InstanceKeys and PointerKeys. This information * is used later on when creating subobject trees for accessed field variables. */ InstanceAndPointerKeyFactoryAdapter adapter = null; InstanceKeyFactory ikFact = builder.getInstanceKeys(); PointerKeyFactory pkFact = builder.getPointerKeyFactory(); adapter = new InstanceAndPointerKeyFactoryAdapter(ikFact, pkFact); builder.setInstanceKeys(adapter); builder.setPointerKeyFactory(adapter); progress.done(); progress.subTask(Messages.getString("Analyzer.SubTask_Call_Graph")); // $NON-NLS-1$ CallGraph cg = builder.makeCallGraph(options, progress); if (cfg.optimizeCg >= 0) { CallGraphPruning opt = new CallGraphPruning(cg); System.out.println("Call Graph has " + cg.getNumberOfNodes() + " Nodes."); Set<CGNode> sopt = opt.findApplicationNodes(cfg.optimizeCg); cg = new PrunedCallGraph(cg, sopt); System.out.println("Optimized Call Graph has " + cg.getNumberOfNodes() + " Nodes."); } if (Debug.Var.DUMP_CALLGRAPH.isSet()) { Util.dumpCallGraph(cg, cfg.mainClass.replace('/', '.').substring(1), progress); } if (Debug.Var.DUMP_HEAP_GRAPH.isSet()) { PointerAnalysis pta = builder.getPointerAnalysis(); HeapGraph hg = pta.getHeapGraph(); Util.dumpHeapGraph( cfg.mainClass.replace('/', '.').substring(1) + "." + cfg.pointsTo, hg, null); } PointerAnalysis pta = builder.getPointerAnalysis(); progress.done(); DemandRefinementPointsTo demandPts = null; if (cfg.useDemandPts) { throw new UnsupportedOperationException(); // MemoryAccessMap mam = new PABasedMemoryAccessMap(cg, builder.getPointerAnalysis()); // demandPts = new DemandRefinementPointsTo(cg, // new ThisFilteringHeapModel(builder,cha), mam, cha, options, getStateMachineFactory()); } IPointerAnalysis pts = new PointsToWrapper(demandPts, pta); progress.subTask(Messages.getString("Analyzer.SubTask_Search_Main")); // $NON-NLS-1$ IMethod main = edu.kit.joana.deprecated.jsdg.util.Util.searchMethod( entrypoints, "main([Ljava/lang/String;)V"); // $NON-NLS-1$ progress.done(); progress.done(); SDG sdg = SDG.create(main, cg, cache, adapter, pts, cfg, progress); sdg.setAnalysisScope(scope); sdg.setPointerAnalysis(pta); progress.done(); if (Debug.Var.PRINT_FIELD_PTS_INFO.isSet()) { Log.info("search for field allocs called " + PDG.searchFieldAllocs + " times."); } if (Debug.Var.PRINT_UNRESOLVED_CLASSES.isSet()) { for (TypeReference tRef : cg.getClassHierarchy().getUnresolvedClasses()) { Log.warn("Could not resolve: " + Util.typeName(tRef.getName())); } } return new Result(null, sdg, cg, pta, null); }