All Downloads are FREE. Search and download functionalities are using the official Maven repository.

boomerang.guided.DemandDrivenGuidedAnalysis Maven / Gradle / Ivy

There is a newer version: 3.2.2
Show newest version
package boomerang.guided;

import boomerang.BackwardQuery;
import boomerang.Boomerang;
import boomerang.BoomerangOptions;
import boomerang.ForwardQuery;
import boomerang.Query;
import boomerang.QueryGraph;
import boomerang.guided.Specification.QueryDirection;
import boomerang.results.AbstractBoomerangResults.Context;
import boomerang.results.BackwardBoomerangResults;
import boomerang.results.ForwardBoomerangResults;
import boomerang.scene.ControlFlowGraph.Edge;
import boomerang.scene.DataFlowScope;
import boomerang.scene.SootDataFlowScope;
import boomerang.scene.Val;
import boomerang.scene.jimple.SootCallGraph;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.common.collect.Table;
import com.google.common.collect.Table.Cell;
import java.util.Collection;
import java.util.LinkedList;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import soot.Scene;
import sync.pds.solver.nodes.Node;
import wpds.impl.Weight.NoWeight;

public class DemandDrivenGuidedAnalysis {

  private final BoomerangOptions customBoomerangOptions;
  private final IDemandDrivenGuidedManager spec;
  private final DataFlowScope scope;
  private final SootCallGraph callGraph;
  private final LinkedList queryQueue = Lists.newLinkedList();
  private final Set visited = Sets.newHashSet();
  private final Boomerang solver;
  private boolean triggered;

  public DemandDrivenGuidedAnalysis(
      IDemandDrivenGuidedManager specification,
      BoomerangOptions options,
      DataFlowScope dataFlowScope) {
    spec = specification;
    callGraph = new SootCallGraph();
    scope = dataFlowScope;
    if (!options.allowMultipleQueries()) {
      throw new RuntimeException(
          "Boomerang options allowMultipleQueries is set to false. Please enable it.");
    }
    customBoomerangOptions = options;
    solver = new Boomerang(callGraph, scope, customBoomerangOptions);
  }

  public DemandDrivenGuidedAnalysis(
      IDemandDrivenGuidedManager specification, BoomerangOptions options) {
    this(specification, options, SootDataFlowScope.make(Scene.v()));
  }

  /**
   * The query graph takes as input an initial query from which all follow up computations are
   * computed. Based on the specification provided. It returns the QueryGraph which is a graph whose
   * nodes are Boomerang Queries, there is an edge between the queries if there node A triggered a
   * subsequent query B.
   *
   * 

Important note: Ensure to call cleanUp() after finishing the analysis. * * @param query The initial query to start the analysis from. * @return a query graph containing all queries triggered. */ public QueryGraph run(Query query) { if (triggered) { throw new RuntimeException( DemandDrivenGuidedAnalysis.class.getName() + " must be instantiated once per query. Use a different instance."); } triggered = true; queryQueue.add(new QueryWithContext(query)); while (!queryQueue.isEmpty()) { QueryWithContext pop = queryQueue.pop(); if (pop.query instanceof ForwardQuery) { ForwardBoomerangResults results; ForwardQuery currentQuery = (ForwardQuery) pop.query; if (pop.parentQuery == null) { results = solver.solve(currentQuery); } else { results = solver.solveUnderScope(currentQuery, pop.triggeringNode, pop.parentQuery); } Table forwardResults = results.asStatementValWeightTable((ForwardQuery) pop.query); // Any ForwardQuery may trigger additional ForwardQuery under its own scope. triggerNewBackwardQueries(forwardResults, currentQuery, QueryDirection.FORWARD); } else { BackwardBoomerangResults results; if (pop.parentQuery == null) { results = solver.solve((BackwardQuery) pop.query); } else { results = solver.solveUnderScope( (BackwardQuery) pop.query, pop.triggeringNode, pop.parentQuery); } Table backwardResults = solver.getBackwardSolvers().get(query).asStatementValWeightTable(); triggerNewBackwardQueries(backwardResults, pop.query, QueryDirection.BACKWARD); Map allocationSites = results.getAllocationSites(); for (Entry entry : allocationSites.entrySet()) { triggerNewBackwardQueries( results.asStatementValWeightTable(entry.getKey()), entry.getKey(), QueryDirection.FORWARD); } } } QueryGraph queryGraph = solver.getQueryGraph(); return queryGraph; } /** * Ensure to call cleanup to detach all listeners from the solver, otherwise the analysis may run * into a Memory issues. */ public void cleanUp() { solver.unregisterAllListeners(); } public Boomerang getSolver() { return solver; } private void triggerNewBackwardQueries( Table backwardResults, Query lastQuery, QueryDirection direction) { for (Cell cell : backwardResults.cellSet()) { Edge triggeringEdge = cell.getRowKey(); Val fact = cell.getColumnKey(); Collection queries; if (direction == QueryDirection.FORWARD) { queries = spec.onForwardFlow((ForwardQuery) lastQuery, cell.getRowKey(), cell.getColumnKey()); } else { queries = spec.onBackwardFlow((BackwardQuery) lastQuery, cell.getRowKey(), cell.getColumnKey()); } for (Query q : queries) { addToQueue(new QueryWithContext(q, new Node<>(triggeringEdge, fact), lastQuery)); } } } private void addToQueue(QueryWithContext nextQuery) { if (visited.add(nextQuery.query)) { queryQueue.add(nextQuery); } } private static class QueryWithContext { private QueryWithContext(Query query) { this.query = query; } private QueryWithContext(Query query, Node triggeringNode, Query parentQuery) { this.query = query; this.parentQuery = parentQuery; this.triggeringNode = triggeringNode; } Query query; Query parentQuery; Node triggeringNode; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy