Example #1
0
  /** Expensive! */
  private void dumpCallGraphReachablesCSV() {
    try {
      FileWriter fw =
          new FileWriter(Project.v().getOutputDir() + File.separator + "reachables-count.csv");

      fw.write("Method,Reachables");

      for (MethodOrMethodContext momc : getReachableMethodContexts()) {
        if ("<clinit>".equals(momc.method().getName())) continue;

        Set<MethodOrMethodContext> c = new HashSet<MethodOrMethodContext>();
        c.add(momc);
        Filter filter = new Filter(noStaticInits);
        // filter on static initializers, hopefully they won't show in the stats,
        // or any calls that they make...
        ReachableMethods rm = new ReachableMethods(callGraph, c.iterator(), filter);
        rm.update();

        QueueReader<MethodOrMethodContext> edges = rm.listener();
        int reachables = 0;
        while (edges.hasNext()) {
          MethodOrMethodContext reachable = edges.next();
          if ("<clinit>".equals(reachable.method().getName())) continue;
          reachables++;
        }

        fw.write(momc + "|" + reachables + "\n");
      }

      fw.close();

    } catch (IOException e) {

    }
  }
Example #2
0
  public void getAllInvolvedMethods() {

    ReachableMethods rm =
        CallGraphHelper.getReachableMethod(Scene.v().getCallGraph(), syncsEnclosingMethods);
    for (Iterator<?> it = rm.listener(); it.hasNext(); ) {
      SootMethod m = (SootMethod) it.next();
      allInvolvedMethod.add(m);
    }
  }
Example #3
0
 public ReachableMethods getReachableMethods() {
   if (reachableMethods == null) {
     reachableMethods =
         new ReachableMethods(
             getCallGraph(), new ArrayList<MethodOrMethodContext>(getEntryPoints()));
   }
   reachableMethods.update();
   return reachableMethods;
 }
Example #4
0
 private void processReachables() {
   reachableMethods.update();
   while (reachablesReader.hasNext()) {
     MethodOrMethodContext m = (MethodOrMethodContext) reachablesReader.next();
     MethodPAG mpag = MethodPAG.v(pag, m.method());
     mpag.build();
     mpag.addToPAG(m.context());
   }
 }
Example #5
0
 public OnFlyCallGraph(PAG pag) {
   this.pag = pag;
   CGOptions options = new CGOptions(PhaseOptions.v().getPhaseOptions("cg"));
   if (options.all_reachable()) {
     List entryPoints = new ArrayList();
     entryPoints.addAll(EntryPoints.v().all());
     entryPoints.addAll(EntryPoints.v().methodsOfApplicationClasses());
     Scene.v().setEntryPoints(entryPoints);
   }
   callGraph = new CallGraph();
   Scene.v().setCallGraph(callGraph);
   ContextManager cm = CallGraphBuilder.makeContextManager(callGraph);
   reachableMethods = Scene.v().getReachableMethods();
   ofcgb = new OnFlyCallGraphBuilder(cm, reachableMethods);
   reachablesReader = reachableMethods.listener();
   callEdges = cm.callGraph().listener();
 }
Example #6
0
  public void assureAllSyncInCallGraph(Collection<JavaCriticalSection> criticalSections) {
    System.out.println("[assureAllSyncInCallgraph] starting");
    Date start = new Date();
    ReachableMethods oldReach = Scene.v().getReachableMethods();
    // Collection et = EntryPoints.v().all();
    // ReachableMethods reachableFromMain = new ReachableMethods(cg, et);
    // reachableFromMain.update();

    Set<SootMethod> notInCG = new HashSet<SootMethod>();
    for (JavaCriticalSection cs : criticalSections) {
      SootMethod m = cs.getSootMethod();
      if (!oldReach.contains(m)) notInCG.add(m);
    }
    Set<SootMethod> alreadyInCG = new HashSet<SootMethod>();
    for (Iterator<MethodOrMethodContext> it = oldReach.listener(); it.hasNext(); ) {
      alreadyInCG.add(it.next().method());
    }
    /*
     * for(Iterator<?> it=cg.sourceMethods();it.hasNext();){ SootMethod m =
     * (SootMethod)it.next(); alreadyInCG.add(m); if(notInCG.contains(m)){
     * notInCG.remove(m); } }
     */

    // add new methods to the call graph
    Stack<SootMethod> worklist = new Stack<SootMethod>();
    for (SootMethod m : notInCG) {
      worklist.push(m);
    }

    while (!worklist.isEmpty()) {
      SootMethod m = worklist.pop();
      if (alreadyInCG.contains(m) || m == null) {
        continue;
      }
      alreadyInCG.add(m);

      Body body = m.retrieveActiveBody();
      for (Unit u : body.getUnits()) {
        if (!(u instanceof Stmt)) {
          continue;
        }

        Stmt s = (Stmt) u;
        if (!s.containsInvokeExpr()) {
          continue;
        }

        InvokeExpr invoke = s.getInvokeExpr();
        SootMethod declCallee = invoke.getMethod();
        Collection<SootMethod> targets = new ArrayList<SootMethod>();
        if (declCallee.isStatic()) {
          targets.add(declCallee);
        } else {
          // XXX: pay attention to reflexive call, thread call, and
          // etc.
          // Here we do not add edges for implicit targets, as these
          // parts of methods is not reachable
          // from the entry, and they will most likely to be analyzed
          // in a very conservative ways.
          InstanceInvokeExpr iie = (InstanceInvokeExpr) invoke;
          Local receiver = (Local) iie.getBase();
          NumberedString subSig = iie.getMethodRef().getSubSignature();

          if (invoke instanceof SpecialInvokeExpr) {
            SootMethod tgt = VirtualCalls.v().resolveSpecial((SpecialInvokeExpr) invoke, subSig, m);
            targets.add(tgt);
          } else {
            Type t = receiver.getType();
            if (t instanceof ArrayType) {
              // t = RefType.v("java.lang.Object");
              targets.add(declCallee);
            }
            // BottomType bug
            else if (t instanceof soot.jimple.toolkits.typing.fast.BottomType) {
              System.out.println("BottomType:" + s);
            } else if (t instanceof soot.NullType) {
              System.out.println("NullType:" + s);
            } else {
              SootClass c = ((RefType) t).getSootClass();
              // Soot has a type resolving bug, and here may be
              // exceptions
              try {
                Set<SootMethod> callees =
                    Scene.v().getOrMakeFastHierarchy().resolveAbstractDispatch(c, declCallee);
                targets.addAll(callees);
              } catch (Exception e) {
                System.out.println(e.getMessage());
              }
            }
          }
        }

        for (SootMethod t : targets) {
          // add call edge
          Edge e = new Edge(m, s, t);
          Scene.v().getCallGraph().addEdge(e);

          // add to worklist
          if (t.isConcrete() && !alreadyInCG.contains(t)) {
            worklist.push(t);
          }
        }
      }
    }

    // infer entries for the methods not reachable from main entry
    List<SootMethod> entries = Scene.v().getEntryPoints();
    _patchedEntries = new ArrayList<SootMethod>(notInCG);
    for (SootMethod m : notInCG) {
      // XXX there can be recursive calls, so for simple processing, all
      // methods not in old
      // call graph should be added to the entry. Checking the
      // non-existence of incoming edges
      // may miss some recursively called methods
      // if(!cg.edgesInto(m).hasNext()){
      entries.add(m);
      // }
    }

    // update reachable methods
    Scene.v().setReachableMethods(null);
  }