use of soot.PointsToAnalysis in project soot by Sable.
the class SparkTransformer method internalTransform.
protected void internalTransform(String phaseName, Map<String, String> options) {
SparkOptions opts = new SparkOptions(options);
final String output_dir = SourceLocator.v().getOutputDir();
// Build pointer assignment graph
ContextInsensitiveBuilder b = new ContextInsensitiveBuilder();
if (opts.pre_jimplify())
b.preJimplify();
if (opts.force_gc())
doGC();
Date startBuild = new Date();
final PAG pag = b.setup(opts);
b.build();
Date endBuild = new Date();
reportTime("Pointer Assignment Graph", startBuild, endBuild);
if (opts.force_gc())
doGC();
// Build type masks
Date startTM = new Date();
pag.getTypeManager().makeTypeMask();
Date endTM = new Date();
reportTime("Type masks", startTM, endTM);
if (opts.force_gc())
doGC();
if (opts.verbose()) {
logger.debug("VarNodes: " + pag.getVarNodeNumberer().size());
logger.debug("FieldRefNodes: " + pag.getFieldRefNodeNumberer().size());
logger.debug("AllocNodes: " + pag.getAllocNodeNumberer().size());
}
// Simplify pag
Date startSimplify = new Date();
// these option interdependencies more cleanly would be nice...
if ((opts.simplify_sccs() && !opts.on_fly_cg()) || opts.vta()) {
new SCCCollapser(pag, opts.ignore_types_for_sccs()).collapse();
}
if (opts.simplify_offline() && !opts.on_fly_cg()) {
new EBBCollapser(pag).collapse();
}
if (true || opts.simplify_sccs() || opts.vta() || opts.simplify_offline()) {
pag.cleanUpMerges();
}
Date endSimplify = new Date();
reportTime("Pointer Graph simplified", startSimplify, endSimplify);
if (opts.force_gc())
doGC();
// Dump pag
PAGDumper dumper = null;
if (opts.dump_pag() || opts.dump_solution()) {
dumper = new PAGDumper(pag, output_dir);
}
if (opts.dump_pag())
dumper.dump();
// Propagate
Date startProp = new Date();
propagatePAG(opts, pag);
Date endProp = new Date();
reportTime("Propagation", startProp, endProp);
reportTime("Solution found", startSimplify, endProp);
if (opts.force_gc())
doGC();
if (!opts.on_fly_cg() || opts.vta()) {
CallGraphBuilder cgb = new CallGraphBuilder(pag);
cgb.build();
}
if (opts.verbose()) {
logger.debug("[Spark] Number of reachable methods: " + Scene.v().getReachableMethods().size());
}
if (opts.set_mass())
findSetMass(pag);
if (opts.dump_answer())
new ReachingTypeDumper(pag, output_dir).dump();
if (opts.dump_solution())
dumper.dumpPointsToSets();
if (opts.dump_html())
new PAG2HTML(pag, output_dir).dump();
Scene.v().setPointsToAnalysis(pag);
if (opts.add_tags()) {
addTags(pag);
}
if (opts.geom_pta()) {
if (opts.simplify_offline() || opts.simplify_sccs()) {
logger.debug("" + "Please turn off the simplify-offline and simplify-sccs to run the geometric points-to analysis");
logger.debug("Now, we keep the SPARK result for querying.");
} else {
// We perform the geometric points-to analysis
GeomPointsTo geomPTA = (GeomPointsTo) pag;
geomPTA.parametrize(endProp.getTime() - startSimplify.getTime());
geomPTA.solve();
}
}
if (opts.cs_demand()) {
// replace by demand-driven refinement-based context-sensitive analysis
Date startOnDemand = new Date();
PointsToAnalysis onDemandAnalysis = DemandCSPointsTo.makeWithBudget(opts.traversal(), opts.passes(), opts.lazy_pts());
Date endOndemand = new Date();
reportTime("Initialized on-demand refinement-based context-sensitive analysis", startOnDemand, endOndemand);
Scene.v().setPointsToAnalysis(onDemandAnalysis);
}
}
use of soot.PointsToAnalysis in project soot by Sable.
the class IFDSPossibleTypes method createFlowFunctionsFactory.
public FlowFunctions<Unit, Pair<Value, Type>, SootMethod> createFlowFunctionsFactory() {
return new FlowFunctions<Unit, Pair<Value, Type>, SootMethod>() {
public FlowFunction<Pair<Value, Type>> getNormalFlowFunction(Unit src, Unit dest) {
if (src instanceof DefinitionStmt) {
DefinitionStmt defnStmt = (DefinitionStmt) src;
if (defnStmt.containsInvokeExpr())
return Identity.v();
final Value right = defnStmt.getRightOp();
final Value left = defnStmt.getLeftOp();
// won't track primitive-typed variables
if (right.getType() instanceof PrimType)
return Identity.v();
if (right instanceof Constant || right instanceof NewExpr) {
return new FlowFunction<Pair<Value, Type>>() {
public Set<Pair<Value, Type>> computeTargets(Pair<Value, Type> source) {
if (source == zeroValue()) {
Set<Pair<Value, Type>> res = new LinkedHashSet<Pair<Value, Type>>();
res.add(new Pair<Value, Type>(left, right.getType()));
res.add(zeroValue());
return res;
} else if (source.getO1() instanceof Local && source.getO1().equivTo(left)) {
// strong update for local variables
return Collections.emptySet();
} else {
return Collections.singleton(source);
}
}
};
} else if (right instanceof Ref || right instanceof Local) {
return new FlowFunction<Pair<Value, Type>>() {
public Set<Pair<Value, Type>> computeTargets(final Pair<Value, Type> source) {
Value value = source.getO1();
if (source.getO1() instanceof Local && source.getO1().equivTo(left)) {
// strong update for local variables
return Collections.emptySet();
} else if (maybeSameLocation(value, right)) {
return new LinkedHashSet<Pair<Value, Type>>() {
{
add(new Pair<Value, Type>(left, source.getO2()));
add(source);
}
};
} else {
return Collections.singleton(source);
}
}
private boolean maybeSameLocation(Value v1, Value v2) {
if (!(v1 instanceof InstanceFieldRef && v2 instanceof InstanceFieldRef) && !(v1 instanceof ArrayRef && v2 instanceof ArrayRef)) {
return v1.equivTo(v2);
}
if (v1 instanceof InstanceFieldRef && v2 instanceof InstanceFieldRef) {
InstanceFieldRef ifr1 = (InstanceFieldRef) v1;
InstanceFieldRef ifr2 = (InstanceFieldRef) v2;
if (!ifr1.getField().getName().equals(ifr2.getField().getName()))
return false;
Local base1 = (Local) ifr1.getBase();
Local base2 = (Local) ifr2.getBase();
PointsToAnalysis pta = Scene.v().getPointsToAnalysis();
PointsToSet pts1 = pta.reachingObjects(base1);
PointsToSet pts2 = pta.reachingObjects(base2);
return pts1.hasNonEmptyIntersection(pts2);
} else {
// v1 instanceof ArrayRef && v2 instanceof ArrayRef
ArrayRef ar1 = (ArrayRef) v1;
ArrayRef ar2 = (ArrayRef) v2;
Local base1 = (Local) ar1.getBase();
Local base2 = (Local) ar2.getBase();
PointsToAnalysis pta = Scene.v().getPointsToAnalysis();
PointsToSet pts1 = pta.reachingObjects(base1);
PointsToSet pts2 = pta.reachingObjects(base2);
return pts1.hasNonEmptyIntersection(pts2);
}
}
};
}
}
return Identity.v();
}
public FlowFunction<Pair<Value, Type>> getCallFlowFunction(final Unit src, final SootMethod dest) {
Stmt stmt = (Stmt) src;
InvokeExpr ie = stmt.getInvokeExpr();
final List<Value> callArgs = ie.getArgs();
final List<Local> paramLocals = new ArrayList<Local>();
for (int i = 0; i < dest.getParameterCount(); i++) {
paramLocals.add(dest.getActiveBody().getParameterLocal(i));
}
return new FlowFunction<Pair<Value, Type>>() {
public Set<Pair<Value, Type>> computeTargets(Pair<Value, Type> source) {
if (!dest.getName().equals("<clinit>") && !dest.getSubSignature().equals("void run()")) {
Value value = source.getO1();
int argIndex = callArgs.indexOf(value);
if (argIndex > -1) {
return Collections.singleton(new Pair<Value, Type>(paramLocals.get(argIndex), source.getO2()));
}
}
return Collections.emptySet();
}
};
}
public FlowFunction<Pair<Value, Type>> getReturnFlowFunction(Unit callSite, SootMethod callee, Unit exitStmt, Unit retSite) {
if (exitStmt instanceof ReturnStmt) {
ReturnStmt returnStmt = (ReturnStmt) exitStmt;
Value op = returnStmt.getOp();
if (op instanceof Local) {
if (callSite instanceof DefinitionStmt) {
DefinitionStmt defnStmt = (DefinitionStmt) callSite;
Value leftOp = defnStmt.getLeftOp();
if (leftOp instanceof Local) {
final Local tgtLocal = (Local) leftOp;
final Local retLocal = (Local) op;
return new FlowFunction<Pair<Value, Type>>() {
public Set<Pair<Value, Type>> computeTargets(Pair<Value, Type> source) {
if (source == retLocal)
return Collections.singleton(new Pair<Value, Type>(tgtLocal, source.getO2()));
return Collections.emptySet();
}
};
}
}
}
}
return KillAll.v();
}
public FlowFunction<Pair<Value, Type>> getCallToReturnFlowFunction(Unit call, Unit returnSite) {
return Identity.v();
}
};
}
Aggregations