1 19 20 package soot.jimple.toolkits.callgraph; 21 import soot.*; 22 import soot.options.*; 23 import soot.jimple.*; 24 import java.util.*; 25 import soot.util.*; 26 import soot.util.queue.*; 27 28 31 public final class CallGraphBuilder 32 { 33 private PointsToAnalysis pa; 34 private CGOptions options; 35 private ReachableMethods reachables; 36 private boolean appOnly = false; 37 private OnFlyCallGraphBuilder ofcgb; 38 private CallGraph cg; 39 40 public CallGraph getCallGraph() { return cg; } 41 public ReachableMethods reachables() { return reachables; } 42 43 public static ContextManager makeContextManager( CallGraph cg ) { 44 return new ContextInsensitiveContextManager( cg ); 45 } 46 47 49 public CallGraphBuilder( PointsToAnalysis pa ) { 50 this.pa = pa; 51 options = new CGOptions( PhaseOptions.v().getPhaseOptions("cg") ); 52 if( options.all_reachable() ) { 53 List entryPoints = new ArrayList(); 54 entryPoints.addAll( EntryPoints.v().all() ); 55 entryPoints.addAll( EntryPoints.v().methodsOfApplicationClasses() ); 56 Scene.v().setEntryPoints( entryPoints ); 57 } 58 cg = new CallGraph(); 59 Scene.v().setCallGraph( cg ); 60 reachables = Scene.v().getReachableMethods(); 61 ContextManager cm = makeContextManager(cg); 62 ofcgb = new OnFlyCallGraphBuilder( cm, reachables ); 63 } 64 69 public CallGraphBuilder() { 70 G.v().out.println( "Warning: using incomplete callgraph containing "+ 71 "only application classes." ); 72 pa = soot.jimple.toolkits.pointer.DumbPointerAnalysis.v(); 73 options = new CGOptions( PhaseOptions.v().getPhaseOptions("cg") ); 74 cg = new CallGraph(); 75 Scene.v().setCallGraph(cg); 76 List entryPoints = new ArrayList(); 77 entryPoints.addAll( EntryPoints.v().methodsOfApplicationClasses() ); 78 entryPoints.addAll( EntryPoints.v().implicit() ); 79 reachables = new ReachableMethods( cg, entryPoints ); 80 appOnly = true; 81 ContextManager cm = new ContextInsensitiveContextManager( cg ); 82 ofcgb = new OnFlyCallGraphBuilder( cm, reachables, true ); 83 } 84 public void build() { 85 QueueReader worklist = reachables.listener(); 86 while(true) { 87 ofcgb.processReachables(); 88 reachables.update(); 89 if( !worklist.hasNext() ) break; 90 MethodOrMethodContext momc = (MethodOrMethodContext) worklist.next(); 91 List receivers = (List) ofcgb.methodToReceivers().get(momc.method()); 92 if( receivers != null) for( Iterator receiverIt = receivers.iterator(); receiverIt.hasNext(); ) { 93 final Local receiver = (Local) receiverIt.next(); 94 final PointsToSet p2set = pa.reachingObjects( receiver ); 95 for( Iterator typeIt = p2set.possibleTypes().iterator(); typeIt.hasNext(); ) { 96 final Type type = (Type) typeIt.next(); 97 ofcgb.addType( receiver, momc.context(), type, null ); 98 } 99 } 100 List stringConstants = (List) ofcgb.methodToStringConstants().get(momc.method()); 101 if( stringConstants != null ) for( Iterator stringConstantIt = stringConstants.iterator(); stringConstantIt.hasNext(); ) { 102 final Local stringConstant = (Local) stringConstantIt.next(); 103 PointsToSet p2set = pa.reachingObjects( stringConstant ); 104 Collection possibleStringConstants = p2set.possibleStringConstants(); 105 if( possibleStringConstants == null ) { 106 ofcgb.addStringConstant( stringConstant, momc.context(), null ); 107 } else { 108 for( Iterator constantIt = possibleStringConstants.iterator(); constantIt.hasNext(); ) { 109 final String constant = (String ) constantIt.next(); 110 ofcgb.addStringConstant( stringConstant, momc.context(), constant ); 111 } 112 } 113 } 114 } 115 } 116 } 117 118 | Popular Tags |