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

boomerang.guided.SimpleSpecificationGuidedManager Maven / Gradle / Ivy

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

import boomerang.BackwardQuery;
import boomerang.ForwardQuery;
import boomerang.Query;
import boomerang.guided.Specification.Parameter;
import boomerang.guided.Specification.QueryDirection;
import boomerang.guided.Specification.QuerySelector;
import boomerang.guided.Specification.SootMethodWithSelector;
import boomerang.scene.AllocVal;
import boomerang.scene.ControlFlowGraph.Edge;
import boomerang.scene.Method;
import boomerang.scene.Statement;
import boomerang.scene.Val;
import boomerang.scene.jimple.JimpleStatement;
import com.google.common.collect.Sets;
import java.util.Collection;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import soot.jimple.Stmt;

public class SimpleSpecificationGuidedManager implements IDemandDrivenGuidedManager {

  private final Specification spec;

  public SimpleSpecificationGuidedManager(Specification spec) {
    this.spec = spec;
  }

  @Override
  public Collection onForwardFlow(ForwardQuery query, Edge dataFlowEdge, Val dataFlowVal) {
    Statement stmt = dataFlowEdge.getStart();
    Set res = Sets.newHashSet();
    if (stmt.containsInvokeExpr()) {
      Set selectors =
          spec.getMethodAndQueries().stream()
              .filter(x -> isInOnList(x, stmt, dataFlowVal, QueryDirection.FORWARD))
              .collect(Collectors.toSet());
      for (SootMethodWithSelector sel : selectors) {
        res.addAll(createNewQueries(sel, stmt));
      }
    }
    return res;
  }

  @Override
  public Collection onBackwardFlow(BackwardQuery query, Edge dataFlowEdge, Val dataFlowVal) {
    Statement stmt = dataFlowEdge.getStart();
    Set res = Sets.newHashSet();
    if (stmt.containsInvokeExpr()) {
      Set selectors =
          spec.getMethodAndQueries().stream()
              .filter(x -> isInOnList(x, stmt, dataFlowVal, QueryDirection.BACKWARD))
              .collect(Collectors.toSet());
      for (SootMethodWithSelector sel : selectors) {
        res.addAll(createNewQueries(sel, stmt));
      }
    }
    return res;
  }

  private Collection createNewQueries(SootMethodWithSelector sel, Statement stmt) {
    Set results = Sets.newHashSet();
    Method method = stmt.getMethod();
    for (QuerySelector qSel : sel.getGo()) {
      Optional parameterVal = getParameterVal(stmt, qSel.argumentSelection);
      if (parameterVal.isPresent()) {
        if (qSel.direction == QueryDirection.BACKWARD) {
          for (Statement pred : method.getControlFlowGraph().getPredsOf(stmt)) {
            results.add(BackwardQuery.make(new Edge(pred, stmt), parameterVal.get()));
          }
        } else if (qSel.direction == QueryDirection.FORWARD) {
          for (Statement succ : method.getControlFlowGraph().getSuccsOf(stmt)) {
            results.add(
                new ForwardQuery(
                    new Edge(stmt, succ),
                    new AllocVal(parameterVal.get(), stmt, parameterVal.get())));
          }
        }
      }
    }
    return results;
  }

  public boolean isInOnList(
      SootMethodWithSelector methodSelector, Statement stmt, Val fact, QueryDirection direction) {
    if (stmt instanceof JimpleStatement) {
      // This only works for Soot propagations
      Stmt jimpleStmt = ((JimpleStatement) stmt).getDelegate();
      if (jimpleStmt
          .getInvokeExpr()
          .getMethod()
          .getSignature()
          .equals(methodSelector.getSootMethod())) {
        Collection on = methodSelector.getOn();
        return isInList(on, direction, stmt, fact);
      }
    }
    return false;
  }

  private boolean isInList(
      Collection list, QueryDirection direction, Statement stmt, Val fact) {
    return list.stream()
        .anyMatch(
            sel -> (sel.direction == direction && isParameter(stmt, fact, sel.argumentSelection)));
  }

  private boolean isParameter(Statement stmt, Val fact, Parameter argumentSelection) {
    if (stmt.getInvokeExpr().isInstanceInvokeExpr() && argumentSelection.equals(Parameter.base())) {
      return stmt.getInvokeExpr().getBase().equals(fact);
    }
    if (argumentSelection.equals(Parameter.returnParam())) {
      return stmt.isAssign() && stmt.getLeftOp().equals(fact);
    }
    return stmt.getInvokeExpr().getArgs().size() > argumentSelection.getValue()
        && argumentSelection.getValue() >= 0
        && stmt.getInvokeExpr().getArg(argumentSelection.getValue()).equals(fact);
  }

  private Optional getParameterVal(Statement stmt, Parameter selector) {
    if (stmt.containsInvokeExpr()
        && !stmt.getInvokeExpr().isStaticInvokeExpr()
        && selector.equals(Parameter.base())) {
      return Optional.of(stmt.getInvokeExpr().getBase());
    }
    if (stmt.isAssign() && selector.equals(Parameter.returnParam())) {
      return Optional.of(stmt.getLeftOp());
    }
    if (stmt.getInvokeExpr().getArgs().size() > selector.getValue() && selector.getValue() >= 0) {
      return Optional.of(stmt.getInvokeExpr().getArg(selector.getValue()));
    }
    return Optional.empty();
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy