private static OrdinalSet<InstanceKey> findReachableInstances( final PointerAnalysis<InstanceKey> pts, final PointerKey pkStart) { final HeapGraph hg = pts.getHeapGraph(); if (!hg.containsNode(pkStart)) { return OrdinalSet.empty(); } final OrdinalSetMapping<InstanceKey> mapping = pts.getInstanceKeyMapping(); final BitVectorIntSet resultSet = new BitVectorIntSet(); final NumberedDFSDiscoverTimeIterator<Object> dfsDiscover = new NumberedDFSDiscoverTimeIterator<Object>(hg, pkStart); while (dfsDiscover.hasNext()) { Object obj = dfsDiscover.next(); if (obj instanceof InstanceKey) { InstanceKey ik = (InstanceKey) obj; final int ikNum = mapping.getMappedIndex(ik); resultSet.add(ikNum); } } final OrdinalSet<InstanceKey> reachable = new OrdinalSet<InstanceKey>(resultSet, mapping); return reachable; }
@Test public void testZeroOneContainerCopyOf() throws IOException, ClassHierarchyException, IllegalArgumentException, CancelException { AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope( TestConstants.WALA_TESTDATA, CallGraphTestUtil.REGRESSION_EXCLUSIONS); ClassHierarchy cha = ClassHierarchy.make(scope); Iterable<Entrypoint> entrypoints = Util.makeMainEntrypoints(scope, cha, "Ldemandpa/TestArraysCopyOf"); AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); AnalysisCache cache = new AnalysisCache(); CallGraphBuilder builder = Util.makeZeroOneContainerCFABuilder(options, cache, cha, scope); CallGraph cg = builder.makeCallGraph(options, null); PointerAnalysis pa = builder.getPointerAnalysis(); CGNode mainMethod = AbstractPtrTest.findMainMethod(cg); PointerKey keyToQuery = AbstractPtrTest.getParam(mainMethod, "testThisVar", pa.getHeapModel()); OrdinalSet<? extends InstanceKey> pointsToSet = pa.getPointsToSet(keyToQuery); Assert.assertEquals(1, pointsToSet.size()); }
private OrdinalSet<InstanceKey> pointsToArrayField(final CGNode node, final int ssaVarBase) { final PointerAnalysis<InstanceKey> pts = sdg.getPointerAnalysis(); final PointerKey pkBase = pts.getHeapModel().getPointerKeyForLocal(node, ssaVarBase); final OrdinalSet<InstanceKey> basePts = pts.getPointsToSet(pkBase); return basePts; // no field sensitivity atm // OrdinalSet<InstanceKey> ptsSet = OrdinalSet.empty(); // for (final InstanceKey ik : basePts) { // final PointerKey fieldPk = pts.getHeapModel().getPointerKeyForArrayContents(ik); // final OrdinalSet<InstanceKey> ptsPart = pts.getPointsToSet(fieldPk); // ptsSet = OrdinalSet.unify(ptsSet, ptsPart); // } // // return ptsSet; }
/** * Compute the set of PointerKeys each statement refs.Be careful to avoid eager PDG construction * here! That means .. don't iterate over SDG statements! */ public static Map<Statement, Set<PointerKey>> scanForRef( SDG sdg, PointerAnalysis pa, ModRef modRef) { if (pa == null) { throw new IllegalArgumentException("null pa"); } ExtendedHeapModel h = new DelegatingExtendedHeapModel(pa.getHeapModel()); Map<Statement, Set<PointerKey>> result = HashMapFactory.make(); for (CGNode n : sdg.getCallGraph()) { IR ir = n.getIR(); if (ir != null) { for (int i = 0; i < ir.getInstructions().length; i++) { SSAInstruction st = ir.getInstructions()[i]; if (st != null) { Set<PointerKey> mod = modRef.getRef(n, h, pa, st, null); if (!mod.isEmpty()) { NormalStatement normal = new NormalStatement(n, i); result.put(normal, mod); } } } } } return result; }
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); }
public static Map<InstanceKey, String> runAnalysisHelper(CallGraph cg, PointerAnalysis pa) throws CancelRuntimeException { logger.debug("*******************************************************"); logger.debug("* Prefix Analysis: Constructing Prefix Transfer Graph *"); final Graph<InstanceKeySite> g = new UriPrefixTransferGraph(pa); logger.debug("* The Graph: *"); logger.debug("*******************************************************"); Iterator<InstanceKeySite> iksI = g.iterator(); while (iksI.hasNext()) { InstanceKeySite iks = iksI.next(); logger.debug("# " + iks); Iterator<InstanceKeySite> edgesI = g.getSuccNodes(iks); while (edgesI.hasNext()) { logger.debug("? \t -->" + edgesI.next()); } } final PrefixTransferFunctionProvider tfp = new PrefixTransferFunctionProvider(); IKilldallFramework<InstanceKeySite, PrefixVariable> framework = new IKilldallFramework<InstanceKeySite, PrefixVariable>() { public Graph<InstanceKeySite> getFlowGraph() { return g; } public ITransferFunctionProvider<InstanceKeySite, PrefixVariable> getTransferFunctionProvider() { return tfp; } }; DataflowSolver<InstanceKeySite, PrefixVariable> dfs = new DataflowSolver<InstanceKeySite, PrefixVariable>(framework) { @Override protected PrefixVariable makeEdgeVariable(InstanceKeySite src, InstanceKeySite dst) { return new PrefixVariable() {}; } @Override protected PrefixVariable makeNodeVariable(InstanceKeySite n, boolean IN) { // TODO Auto-generated method stub PrefixVariable var = new PrefixVariable() {}; // if (n instanceof StringBuilderToStringInstanceKeySite) // var.setOrderNumber(0); // else var.setOrderNumber(10); // var.add(3); return var; } @Override protected PrefixVariable[] makeStmtRHS(int size) { return new PrefixVariable[size]; } }; logger.debug("\n**************************************************"); logger.debug("* Running Analysis"); try { dfs.solve(new EmptyProgressMonitor()); } catch (CancelException e) { throw new CancelRuntimeException(e); } Map<InstanceKey, String> prefixes = new HashMap<InstanceKey, String>(); iksI = g.iterator(); while (iksI.hasNext()) { InstanceKeySite iks = iksI.next(); prefixes.put( pa.getInstanceKeyMapping().getMappedObject(iks.instanceID()), dfs.getOut(iks).knownPrefixes.get(iks.instanceID())); // logger.debug(iks + " ~> " + dfs.getOut(iks)); } // logger.debug("\nLocalPointerKeys that point to String constants: \n" + stringConstants); for (Entry<InstanceKey, String> e : prefixes.entrySet()) { logger.debug(pa.getInstanceKeyMapping().getMappedIndex(e.getKey()) + "\t~> " + e.getValue()); } // TODO: populate prefixes return prefixes; }
private OrdinalSet<InstanceKey> findReachableInstances(final CGNode node, final int ssaVar) { final PointerAnalysis<InstanceKey> pts = sdg.getPointerAnalysis(); final PointerKey pkStart = pts.getHeapModel().getPointerKeyForLocal(node, ssaVar); return findReachableInstances(pts, pkStart); }