use of soot.jimple.spark.pag.AllocNode in project soot by Sable.
the class GeomPointsTo method finalizeInternalData.
/**
* 1. Update the call graph;
* 2. Eliminate the pointers, objects, and constraints related to the unreachable code.
*/
private void finalizeInternalData() {
// Compute the set of reachable functions after the points-to analysis
markReachableMethods();
// Clean the unreachable objects
for (Iterator<IVarAbstraction> it = allocations.iterator(); it.hasNext(); ) {
IVarAbstraction po = it.next();
AllocNode obj = (AllocNode) po.getWrappedNode();
SootMethod sm = obj.getMethod();
if (sm != null && func2int.containsKey(sm) == false)
it.remove();
}
// Clean the unreachable pointers
final Vector<AllocNode> removeSet = new Vector<AllocNode>();
for (Iterator<IVarAbstraction> it = pointers.iterator(); it.hasNext(); ) {
IVarAbstraction pn = it.next();
// Is this pointer obsoleted?
Node vn = pn.getWrappedNode();
SootMethod sm = null;
if (vn instanceof LocalVarNode) {
sm = ((LocalVarNode) vn).getMethod();
} else if (vn instanceof AllocDotField) {
sm = ((AllocDotField) vn).getBase().getMethod();
}
if (sm != null) {
if (func2int.containsKey(sm) == false) {
pn.deleteAll();
vn.discardP2Set();
it.remove();
continue;
}
}
if (pn.getRepresentative() != pn)
continue;
removeSet.clear();
if (pn.hasPTResult()) {
// We remove the useless shapes or objects
Set<AllocNode> objSet = pn.get_all_points_to_objects();
for (Iterator<AllocNode> oit = objSet.iterator(); oit.hasNext(); ) {
AllocNode obj = oit.next();
IVarAbstraction po = consG.get(obj);
if (!po.reachable() || pn.isDeadObject(obj)) {
removeSet.add(obj);
}
}
for (AllocNode obj : removeSet) pn.remove_points_to(obj);
pn.drop_duplicates();
} else {
// We also remove unreachable objects for SPARK nodes
PointsToSetInternal pts = vn.getP2Set();
pts.forall(new P2SetVisitor() {
@Override
public void visit(Node n) {
IVarAbstraction pan = findInternalNode(n);
// The removeSet is misused as a contains set
if (pan.reachable())
removeSet.add((AllocNode) n);
}
});
pts = vn.makeP2Set();
for (AllocNode an : removeSet) pts.add(an);
}
}
// Clean the useless constraints
for (Iterator<PlainConstraint> cIt = constraints.iterator(); cIt.hasNext(); ) {
PlainConstraint cons = cIt.next();
IVarAbstraction lhs = cons.getLHS();
IVarAbstraction rhs = cons.getRHS();
if (!lhs.reachable() || !rhs.reachable() || getMethodIDFromPtr(lhs) == Constants.UNKNOWN_FUNCTION || getMethodIDFromPtr(rhs) == Constants.UNKNOWN_FUNCTION) {
cIt.remove();
}
}
// We reassign the IDs to the pointers, objects and constraints
pointers.reassign();
allocations.reassign();
constraints.reassign();
}
use of soot.jimple.spark.pag.AllocNode in project soot by Sable.
the class GeomPointsTo method reachingObjects.
@Override
public PointsToSet reachingObjects(Local l) {
if (!hasExecuted)
return super.reachingObjects(l);
LocalVarNode vn = findLocalVarNode(l);
if (vn == null)
return EmptyPointsToSet.v();
IVarAbstraction pn = consG.get(vn);
// This is perhaps a bug
if (pn == null)
return vn.getP2Set();
// Return the cached result
if (hasTransformed || vn.getP2Set() != EmptyPointsToSet.v())
return vn.getP2Set();
// Compute and cache the result
pn = pn.getRepresentative();
PointsToSetInternal ptSet = vn.makeP2Set();
for (AllocNode obj : pn.get_all_points_to_objects()) {
ptSet.add(obj);
}
return ptSet;
}
use of soot.jimple.spark.pag.AllocNode in project soot by Sable.
the class GeomPointsTo method reachingObjects.
@Override
public PointsToSet reachingObjects(SootField f) {
if (!hasExecuted)
return super.reachingObjects(f);
if (!f.isStatic())
throw new RuntimeException("The parameter f must be a *static* field.");
VarNode vn = findGlobalVarNode(f);
if (vn == null)
return EmptyPointsToSet.v();
IVarAbstraction pn = consG.get(vn);
if (pn == null)
return vn.getP2Set();
// Lookup the cache
if (hasTransformed || vn.getP2Set() != EmptyPointsToSet.v())
return vn.getP2Set();
// We transform and cache the result for the next query
pn = pn.getRepresentative();
PointsToSetInternal ptSet = vn.makeP2Set();
for (AllocNode obj : pn.getRepresentative().get_all_points_to_objects()) {
ptSet.add(obj);
}
return ptSet;
}
use of soot.jimple.spark.pag.AllocNode in project soot by Sable.
the class GeomPointsTo method field_p2set.
// --------------------------------------------------------------------------------------------------------
// -------------------------------Soot Standard Points-to Query Interface----------------------------------
// --------------------------------------------------------------------------------------------------------
private PointsToSetInternal field_p2set(PointsToSet s, final SparkField f) {
if (!(s instanceof PointsToSetInternal))
throw new RuntimeException("Base pointers must be stored in *PointsToSetInternal*.");
PointsToSetInternal bases = (PointsToSetInternal) s;
final PointsToSetInternal ret = getSetFactory().newSet(f.getType(), this);
bases.forall(new P2SetVisitor() {
public final void visit(Node n) {
Node nDotF = ((AllocNode) n).dot(f);
if (nDotF != null) {
// nDotF.getP2Set() has been discarded in solve()
IVarAbstraction pn = consG.get(nDotF);
if (pn == null || hasTransformed || nDotF.getP2Set() != EmptyPointsToSet.v()) {
ret.addAll(nDotF.getP2Set(), null);
return;
}
pn = pn.getRepresentative();
// PointsToSetInternal ptSet = nDotF.makeP2Set();
for (AllocNode obj : pn.get_all_points_to_objects()) {
ret.add(obj);
// ptSet.add(obj);
}
}
}
});
return ret;
}
use of soot.jimple.spark.pag.AllocNode in project soot by Sable.
the class GeomPointsTo method reachingObjects.
/*
* Currently, we only accept one call unit context (1CFA).
* For querying K-CFA (K >1), please see GeomQueries.contextsByCallChain
*/
@Override
public PointsToSet reachingObjects(Context c, Local l) {
if (!hasExecuted)
return super.reachingObjects(c, l);
if (hasTransformed || !(c instanceof Unit))
return reachingObjects(l);
LocalVarNode vn = findLocalVarNode(l);
if (vn == null)
return EmptyPointsToSet.v();
// Lookup the context sensitive points-to information for this pointer
IVarAbstraction pn = consG.get(vn);
if (pn == null)
return vn.getP2Set();
pn = pn.getRepresentative();
// Obtain the context sensitive points-to result
SootMethod callee = vn.getMethod();
Edge e = Scene.v().getCallGraph().findEdge((Unit) c, callee);
if (e == null)
return vn.getP2Set();
// Compute the contexts interval
CgEdge myEdge = getInternalEdgeFromSootEdge(e);
if (myEdge == null)
return vn.getP2Set();
long low = myEdge.map_offset;
long high = low + max_context_size_block[myEdge.s];
// Lookup the cache
ContextVarNode cvn = vn.context(c);
if (cvn != null) {
PointsToSetInternal ans = cvn.getP2Set();
if (ans != EmptyPointsToSet.v())
return ans;
} else {
// Create a new context sensitive variable
// The points-to vector is set to empty at start
cvn = makeContextVarNode(vn, c);
}
// Fill
PointsToSetInternal ptset = cvn.makeP2Set();
for (AllocNode an : pn.get_all_points_to_objects()) {
if (pn.pointer_interval_points_to(low, high, an))
ptset.add(an);
}
return ptset;
}
Aggregations