use of soot.jimple.spark.pag.Node in project soot by Sable.
the class FullSensitiveNode method do_before_propagation.
@Override
public void do_before_propagation() {
// We first perform the geometric merging
do_pts_interval_merge();
do_flow_edge_interval_merge();
/*
* The following code eliminates the spurious points-to relation for THIS pointer.
* For example we have two classes A and B, B is a child class of A.
* We have a virtual function foo defined in both A and B.
* We have a pointer p in type A.
* pts(p) = { o1, o2 }, where o1 is in type A and o2 is in type B.
* Therefore, the call p.foo() will be resolved to call both A::foo and B::foo.
* Then, in the points-to analysis, we have two assignments: p -> A::foo.THIS, p -> B::foo.THIS
* At this time, obviously, although with the type filter, A::foo.THIS will receive the object o2, which is definitely a fake.
* Thus, we need a new filter to guarantee that A::foo.THIS only points to o1.
* We call this filter "this pointer filter".
*/
Node wrappedNode = getWrappedNode();
if (wrappedNode instanceof LocalVarNode && ((LocalVarNode) wrappedNode).isThisPtr()) {
SootMethod func = ((LocalVarNode) wrappedNode).getMethod();
if (!func.isConstructor()) {
// We don't process the specialinvoke call edge
SootClass defClass = func.getDeclaringClass();
Hierarchy typeHierarchy = Scene.v().getActiveHierarchy();
for (Iterator<AllocNode> it = new_pts.keySet().iterator(); it.hasNext(); ) {
AllocNode obj = it.next();
if (obj.getType() instanceof RefType) {
SootClass sc = ((RefType) obj.getType()).getSootClass();
if (defClass != sc) {
try {
SootMethod rt_func = typeHierarchy.resolveConcreteDispatch(sc, func);
if (rt_func != func) {
it.remove();
// Also preclude it from propagation again
pt_objs.put(obj, (GeometricManager) deadManager);
}
} catch (RuntimeException e) {
// If the input program has a wrong type cast, resolveConcreteDispatch fails and it goes here
// We simply ignore this error
}
}
}
}
}
}
}
use of soot.jimple.spark.pag.Node in project soot by Sable.
the class SootUtil method storesOnField.
public static FieldToEdgesMap storesOnField(PAG pag) {
FieldToEdgesMap storesOnField = new FieldToEdgesMap();
Iterator frNodeIter = pag.storeInvSourcesIterator();
while (frNodeIter.hasNext()) {
FieldRefNode frNode = (FieldRefNode) frNodeIter.next();
VarNode source = frNode.getBase();
SparkField field = frNode.getField();
Node[] targets = pag.storeInvLookup(frNode);
for (int i = 0; i < targets.length; i++) {
VarNode target = (VarNode) targets[i];
storesOnField.put(field, new Pair<VarNode, VarNode>(target, source));
}
}
return storesOnField;
}
use of soot.jimple.spark.pag.Node in project soot by Sable.
the class SootUtil method checkSetsEqual.
@SuppressWarnings("unused")
private static void checkSetsEqual(final HybridPointsToSet intersection, final PointsToSetInternal set1, final PointsToSetInternal set2, PAG pag) {
final PointsToSetInternal ret = new HybridPointsToSet(Scene.v().getObjectType(), pag);
set1.forall(new P2SetVisitor() {
@Override
public void visit(Node n) {
if (set2.contains(n))
ret.add(n);
}
});
ret.forall(new P2SetVisitor() {
@Override
public void visit(Node n) {
// TODO Auto-generated method stub
if (!intersection.contains(n)) {
logger.debug("" + n + " missing from intersection");
logger.debug("" + set1);
logger.debug("" + set2);
logger.debug("" + intersection);
logger.debug("" + ret);
throw new RuntimeException("intersection too small");
}
}
});
intersection.forall(new P2SetVisitor() {
@Override
public void visit(Node n) {
// TODO Auto-generated method stub
if (!ret.contains(n)) {
logger.debug("" + n + " missing from ret");
logger.debug("" + set1);
logger.debug("" + set2);
logger.debug("" + intersection);
logger.debug("" + ret);
throw new RuntimeException("old way too small???");
}
}
});
}
use of soot.jimple.spark.pag.Node in project soot by Sable.
the class OnFlyCallGraph method updatedNode.
public void updatedNode(VarNode vn) {
Object r = vn.getVariable();
if (!(r instanceof Local))
return;
final Local receiver = (Local) r;
final Context context = vn.context();
PointsToSetInternal p2set = vn.getP2Set().getNewSet();
if (ofcgb.wantTypes(receiver)) {
p2set.forall(new P2SetVisitor() {
public final void visit(Node n) {
if (n instanceof AllocNode)
ofcgb.addType(receiver, context, n.getType(), (AllocNode) n);
}
});
}
if (ofcgb.wantStringConstants(receiver)) {
p2set.forall(new P2SetVisitor() {
public final void visit(Node n) {
if (n instanceof StringConstantNode) {
String constant = ((StringConstantNode) n).getString();
ofcgb.addStringConstant(receiver, context, constant);
} else {
ofcgb.addStringConstant(receiver, context, null);
}
}
});
}
if (ofcgb.wantInvokeArg(receiver)) {
p2set.forall(new P2SetVisitor() {
@Override
public void visit(Node n) {
if (n instanceof AllocNode) {
AllocNode an = ((AllocNode) n);
ofcgb.addInvokeArgDotField(receiver, an.dot(ArrayElement.v()));
assert an.getNewExpr() instanceof NewArrayExpr;
NewArrayExpr nae = (NewArrayExpr) an.getNewExpr();
if (!(nae.getSize() instanceof IntConstant)) {
ofcgb.setArgArrayNonDetSize(receiver, context);
} else {
IntConstant sizeConstant = (IntConstant) nae.getSize();
ofcgb.addPossibleArgArraySize(receiver, sizeConstant.value, context);
}
}
}
});
for (Type ty : pag.reachingObjectsOfArrayElement(p2set).possibleTypes()) {
ofcgb.addInvokeArgType(receiver, context, ty);
}
}
}
use of soot.jimple.spark.pag.Node in project soot by Sable.
the class DotPointerGraph method dump.
public void dump(String filename) {
PrintWriter pw = null;
try {
pw = new PrintWriter(new FileOutputStream(filename));
} catch (FileNotFoundException e) {
logger.error(e.getMessage(), e);
}
// pw.println("digraph G {\n\trankdir=LR;");
pw.println("digraph G {");
Predicate<Node> falsePred = new Predicate<Node>() {
@Override
public boolean test(Node obj_) {
return false;
}
};
for (Node node : nodes) {
pw.println(PagToDotDumper.makeDotNodeLabel(node, falsePred));
}
for (String edge : edges) {
pw.println(edge);
}
pw.println("}");
pw.close();
}
Aggregations