package soot.jimple.toolkits.thread.mhp; import soot.*; import java.util.*; import soot.toolkits.graph.*; import soot.jimple.toolkits.callgraph.*; import soot.jimple.*; import soot.jimple.spark.pag.*; // StartJoinFinder written by Richard L. Halpert, 2006-12-04 // This can be used as an alternative to PegGraph and PegChain // if only thread start, join, and type information is needed public class StartJoinFinder { Set<Stmt> startStatements; Set<Stmt> joinStatements; Map<Stmt, List<SootMethod>> startToRunMethods; Map<Stmt, List<AllocNode>> startToAllocNodes; Map<Stmt, Stmt> startToJoin; Map<Stmt, SootMethod> startToContainingMethod; public StartJoinFinder(CallGraph callGraph, PAG pag) { startStatements = new HashSet<Stmt>(); joinStatements = new HashSet<Stmt>(); startToRunMethods = new HashMap<Stmt, List<SootMethod>>(); startToAllocNodes = new HashMap<Stmt, List<AllocNode>>(); startToJoin = new HashMap<Stmt, Stmt>(); startToContainingMethod = new HashMap<Stmt, SootMethod>(); Iterator runAnalysisClassesIt = Scene.v().getApplicationClasses().iterator(); while (runAnalysisClassesIt.hasNext()) { SootClass appClass = (SootClass) runAnalysisClassesIt.next(); Iterator methodsIt = appClass.getMethods().iterator(); while (methodsIt.hasNext()) { SootMethod method = (SootMethod) methodsIt.next(); // If this method may have a start or run method as a target, then do a start/join analysis boolean mayHaveStartStmt = false; Iterator edgesIt = callGraph.edgesOutOf( method ); while(edgesIt.hasNext()) { SootMethod target = ((Edge) edgesIt.next()).tgt(); if(target.getName().equals("start") || target.getName().equals("run")) mayHaveStartStmt = true; } if(mayHaveStartStmt && method.isConcrete()) { Body b = method.retrieveActiveBody(); // run the intraprocedural analysis StartJoinAnalysis sja = new StartJoinAnalysis(new ExceptionalUnitGraph(b), method, callGraph, pag); // Add to interprocedural results startStatements.addAll(sja.getStartStatements()); joinStatements.addAll(sja.getJoinStatements()); startToRunMethods.putAll(sja.getStartToRunMethods()); startToAllocNodes.putAll(sja.getStartToAllocNodes()); startToJoin.putAll(sja.getStartToJoin()); Iterator<Stmt> startIt = sja.getStartStatements().iterator(); while(startIt.hasNext()) { Stmt start = startIt.next(); startToContainingMethod.put(start, method); } } } } } public Set<Stmt> getStartStatements() { return startStatements; } public Set<Stmt> getJoinStatements() { return joinStatements; } public Map<Stmt, List<SootMethod>> getStartToRunMethods() { return startToRunMethods; } public Map<Stmt, List<AllocNode>> getStartToAllocNodes() { return startToAllocNodes; } public Map<Stmt, Stmt> getStartToJoin() { return startToJoin; } public Map<Stmt, SootMethod> getStartToContainingMethod() { return startToContainingMethod; } }