use of soot.jimple.spark.pag.LocalVarNode 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.LocalVarNode 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.LocalVarNode 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;
}
use of soot.jimple.spark.pag.LocalVarNode in project soot by Sable.
the class GeomPointsTo method mergeLocalVariables.
/**
* As pointed out by the single entry graph contraction, temporary variables incur high redundancy in points-to relations.
* Find and eliminate the redundancies as early as possible.
*
* Methodology:
* If q has unique incoming edge p -> q, p and q are both local to the same function, and they have the same type, we merge them.
*/
private void mergeLocalVariables() {
IVarAbstraction my_lhs, my_rhs;
Node lhs, rhs;
int[] count = new int[pointers.size()];
// We count how many ways a local pointer can be assigned
for (PlainConstraint cons : constraints) {
my_lhs = cons.getLHS();
my_rhs = cons.getRHS();
switch(cons.type) {
case Constants.NEW_CONS:
case Constants.ASSIGN_CONS:
count[my_rhs.id]++;
break;
case Constants.LOAD_CONS:
lhs = my_lhs.getWrappedNode();
count[my_rhs.id] += lhs.getP2Set().size();
break;
}
}
// Second time scan, we delete those constraints that only duplicate points-to information
for (Iterator<PlainConstraint> cons_it = constraints.iterator(); cons_it.hasNext(); ) {
PlainConstraint cons = cons_it.next();
if (cons.type == Constants.ASSIGN_CONS) {
my_lhs = cons.getLHS();
my_rhs = cons.getRHS();
lhs = my_lhs.getWrappedNode();
rhs = my_rhs.getWrappedNode();
if ((lhs instanceof LocalVarNode) && (rhs instanceof LocalVarNode)) {
SootMethod sm1 = ((LocalVarNode) lhs).getMethod();
SootMethod sm2 = ((LocalVarNode) rhs).getMethod();
if (sm1 == sm2 && count[my_rhs.id] == 1 && lhs.getType() == rhs.getType()) {
// They are local to the same function and the receiver pointer has unique incoming edge
// More importantly, they have the same type.
my_rhs.merge(my_lhs);
cons_it.remove();
}
}
}
}
// Third scan, update the constraints with the representatives
for (PlainConstraint cons : constraints) {
my_lhs = cons.getLHS();
my_rhs = cons.getRHS();
switch(cons.type) {
case Constants.NEW_CONS:
cons.setRHS(my_rhs.getRepresentative());
break;
case Constants.ASSIGN_CONS:
case Constants.LOAD_CONS:
case Constants.STORE_CONS:
cons.setLHS(my_lhs.getRepresentative());
cons.setRHS(my_rhs.getRepresentative());
break;
}
}
}
use of soot.jimple.spark.pag.LocalVarNode in project soot by Sable.
the class OfflineProcessor method setAllUserCodeVariablesUseful.
/**
* All the pointers that we need their points-to information are marked.
* @param virtualBaseSet
*/
protected void setAllUserCodeVariablesUseful() {
for (int i = 0; i < n_var; ++i) {
IVarAbstraction pn = int2var.get(i);
if (pn != pn.getRepresentative())
continue;
Node node = pn.getWrappedNode();
int sm_id = geomPTA.getMethodIDFromPtr(pn);
if (!geomPTA.isReachableMethod(sm_id))
continue;
if (node instanceof VarNode) {
// flag == true if node is defined in the Java library
boolean defined_in_lib = false;
if (node instanceof LocalVarNode) {
defined_in_lib = ((LocalVarNode) node).getMethod().isJavaLibraryMethod();
} else if (node instanceof GlobalVarNode) {
SootClass sc = ((GlobalVarNode) node).getDeclaringClass();
if (sc != null)
defined_in_lib = sc.isJavaLibraryClass();
}
if (!defined_in_lib && !geomPTA.isExceptionPointer(node)) {
// Defined in the user code
pn.willUpdate = true;
}
}
}
}
Aggregations