use of soot.jimple.spark.sets.P2SetVisitor in project soot by Sable.
the class PropWorklist method propagate.
/**
* Actually does the propagation.
*/
public final void propagate() {
ofcg = pag.getOnFlyCallGraph();
new TopoSorter(pag, false).sort();
for (AllocNode object : pag.allocSources()) {
handleAllocNode(object);
}
boolean verbose = pag.getOpts().verbose();
do {
if (verbose) {
logger.debug("Worklist has " + varNodeWorkList.size() + " nodes.");
}
while (!varNodeWorkList.isEmpty()) {
VarNode src = varNodeWorkList.iterator().next();
varNodeWorkList.remove(src);
handleVarNode(src);
}
if (verbose) {
logger.debug("Now handling field references");
}
for (Object object : pag.storeSources()) {
final VarNode src = (VarNode) object;
Node[] targets = pag.storeLookup(src);
for (Node element0 : targets) {
final FieldRefNode target = (FieldRefNode) element0;
target.getBase().makeP2Set().forall(new P2SetVisitor() {
public final void visit(Node n) {
AllocDotField nDotF = pag.makeAllocDotField((AllocNode) n, target.getField());
if (ofcg != null) {
ofcg.updatedFieldRef(nDotF, src.getP2Set());
}
nDotF.makeP2Set().addAll(src.getP2Set(), null);
}
});
}
}
HashSet<Object[]> edgesToPropagate = new HashSet<Object[]>();
for (Object object : pag.loadSources()) {
handleFieldRefNode((FieldRefNode) object, edgesToPropagate);
}
Set<PointsToSetInternal> nodesToFlush = Collections.newSetFromMap(new IdentityHashMap<PointsToSetInternal, Boolean>());
for (Object[] pair : edgesToPropagate) {
PointsToSetInternal nDotF = (PointsToSetInternal) pair[0];
PointsToSetInternal newP2Set = nDotF.getNewSet();
VarNode loadTarget = (VarNode) pair[1];
if (loadTarget.makeP2Set().addAll(newP2Set, null)) {
varNodeWorkList.add(loadTarget);
}
nodesToFlush.add(nDotF);
}
for (PointsToSetInternal nDotF : nodesToFlush) {
nDotF.flushNew();
}
} while (!varNodeWorkList.isEmpty());
}
use of soot.jimple.spark.sets.P2SetVisitor in project soot by Sable.
the class PropWorklist method handleVarNode.
/**
* Propagates new points-to information of node src to all its successors.
*/
protected final boolean handleVarNode(final VarNode src) {
boolean ret = false;
boolean flush = true;
if (src.getReplacement() != src)
throw new RuntimeException("Got bad node " + src + " with rep " + src.getReplacement());
final PointsToSetInternal newP2Set = src.getP2Set().getNewSet();
if (newP2Set.isEmpty())
return false;
if (ofcg != null) {
QueueReader<Node> addedEdges = pag.edgeReader();
ofcg.updatedNode(src);
ofcg.build();
while (addedEdges.hasNext()) {
Node addedSrc = (Node) addedEdges.next();
Node addedTgt = (Node) addedEdges.next();
ret = true;
if (addedSrc instanceof VarNode) {
VarNode edgeSrc = (VarNode) addedSrc.getReplacement();
if (addedTgt instanceof VarNode) {
VarNode edgeTgt = (VarNode) addedTgt.getReplacement();
if (edgeTgt.makeP2Set().addAll(edgeSrc.getP2Set(), null)) {
varNodeWorkList.add(edgeTgt);
if (edgeTgt == src)
flush = false;
}
} else if (addedTgt instanceof NewInstanceNode) {
NewInstanceNode edgeTgt = (NewInstanceNode) addedTgt.getReplacement();
if (edgeTgt.makeP2Set().addAll(edgeSrc.getP2Set(), null)) {
for (Node element : pag.assignInstanceLookup(edgeTgt)) {
varNodeWorkList.add((VarNode) element);
if (element == src)
flush = false;
}
}
}
} else if (addedSrc instanceof AllocNode) {
VarNode edgeTgt = (VarNode) addedTgt.getReplacement();
if (edgeTgt.makeP2Set().add(addedSrc)) {
varNodeWorkList.add(edgeTgt);
if (edgeTgt == src)
flush = false;
}
} else if (addedSrc instanceof NewInstanceNode && addedTgt instanceof VarNode) {
final NewInstanceNode edgeSrc = (NewInstanceNode) addedSrc.getReplacement();
final VarNode edgeTgt = (VarNode) addedTgt.getReplacement();
addedSrc.getP2Set().forall(new P2SetVisitor() {
@Override
public void visit(Node n) {
if (n instanceof ClassConstantNode) {
ClassConstantNode ccn = (ClassConstantNode) n;
Type ccnType = ccn.getClassConstant().toSootType();
// If the referenced class has not been loaded,
// we do this now
SootClass targetClass = ((RefType) ccnType).getSootClass();
if (targetClass.resolvingLevel() == SootClass.DANGLING)
Scene.v().forceResolve(targetClass.getName(), SootClass.SIGNATURES);
// We can only create alloc nodes for types that
// we know
edgeTgt.makeP2Set().add(pag.makeAllocNode(edgeSrc.getValue(), ccnType, ccn.getMethod()));
varNodeWorkList.add(edgeTgt);
}
}
});
if (edgeTgt.makeP2Set().add(addedSrc)) {
if (edgeTgt == src)
flush = false;
}
}
}
}
Node[] simpleTargets = pag.simpleLookup(src);
for (Node element : simpleTargets) {
if (element.makeP2Set().addAll(newP2Set, null)) {
varNodeWorkList.add((VarNode) element);
if (element == src)
flush = false;
ret = true;
}
}
Node[] storeTargets = pag.storeLookup(src);
for (Node element : storeTargets) {
final FieldRefNode fr = (FieldRefNode) element;
final SparkField f = fr.getField();
ret = fr.getBase().getP2Set().forall(new P2SetVisitor() {
public final void visit(Node n) {
AllocDotField nDotF = pag.makeAllocDotField((AllocNode) n, f);
if (nDotF.makeP2Set().addAll(newP2Set, null)) {
returnValue = true;
}
}
}) | ret;
}
final HashSet<Node[]> storesToPropagate = new HashSet<Node[]>();
final HashSet<Node[]> loadsToPropagate = new HashSet<Node[]>();
for (final FieldRefNode fr : src.getAllFieldRefs()) {
final SparkField field = fr.getField();
final Node[] storeSources = pag.storeInvLookup(fr);
if (storeSources.length > 0) {
newP2Set.forall(new P2SetVisitor() {
public final void visit(Node n) {
AllocDotField nDotF = pag.makeAllocDotField((AllocNode) n, field);
for (Node element : storeSources) {
Node[] pair = { element, nDotF.getReplacement() };
storesToPropagate.add(pair);
}
}
});
}
final Node[] loadTargets = pag.loadLookup(fr);
if (loadTargets.length > 0) {
newP2Set.forall(new P2SetVisitor() {
public final void visit(Node n) {
AllocDotField nDotF = pag.makeAllocDotField((AllocNode) n, field);
if (nDotF != null) {
for (Node element : loadTargets) {
Node[] pair = { nDotF.getReplacement(), element };
loadsToPropagate.add(pair);
}
}
}
});
}
}
if (flush)
src.getP2Set().flushNew();
for (Node[] p : storesToPropagate) {
VarNode storeSource = (VarNode) p[0];
AllocDotField nDotF = (AllocDotField) p[1];
if (nDotF.makeP2Set().addAll(storeSource.getP2Set(), null)) {
ret = true;
}
}
for (Node[] p : loadsToPropagate) {
AllocDotField nDotF = (AllocDotField) p[0];
VarNode loadTarget = (VarNode) p[1];
if (loadTarget.makeP2Set().addAll(nDotF.getP2Set(), null)) {
varNodeWorkList.add(loadTarget);
ret = true;
}
}
return ret;
}
use of soot.jimple.spark.sets.P2SetVisitor in project soot by Sable.
the class PAG2HTML method dumpVarNode.
protected void dumpVarNode(VarNode v, JarOutputStream jarOut) throws IOException {
jarOut.putNextEntry(new ZipEntry("nodes/n" + v.getNumber() + ".html"));
final PrintWriter out = new PrintWriter(jarOut);
out.println("<html>");
out.println("Green node for:");
out.println(varNodeReps(v));
out.println("Declared type: " + v.getType());
out.println("<hr>Reaching blue nodes:");
out.println("<ul>");
v.getP2Set().forall(new P2SetVisitor() {
public final void visit(Node n) {
out.println("<li>" + htmlify(n.toString()));
}
});
out.println("</ul>");
out.println("<hr>Outgoing edges:");
Node[] succs = pag.simpleLookup(v);
for (Node element : succs) {
VarNode succ = (VarNode) element;
out.println(varNodeReps(succ));
}
out.println("<hr>Incoming edges: ");
succs = pag.simpleInvLookup(v);
for (Node element : succs) {
VarNode succ = (VarNode) element;
out.println(varNodeReps(succ));
}
out.println("</html>");
out.flush();
}
use of soot.jimple.spark.sets.P2SetVisitor in project soot by Sable.
the class CallGraphBuilder method build.
public void build() {
QueueReader<MethodOrMethodContext> worklist = reachables.listener();
while (true) {
ofcgb.processReachables();
reachables.update();
if (!worklist.hasNext())
break;
final MethodOrMethodContext momc = worklist.next();
List<Local> receivers = ofcgb.methodToReceivers().get(momc.method());
if (receivers != null)
for (Iterator<Local> receiverIt = receivers.iterator(); receiverIt.hasNext(); ) {
final Local receiver = receiverIt.next();
final PointsToSet p2set = pa.reachingObjects(receiver);
for (Iterator<Type> typeIt = p2set.possibleTypes().iterator(); typeIt.hasNext(); ) {
final Type type = typeIt.next();
ofcgb.addType(receiver, momc.context(), type, null);
}
}
List<Local> bases = ofcgb.methodToInvokeArgs().get(momc.method());
if (bases != null) {
for (Local base : bases) {
PointsToSet pts = pa.reachingObjects(base);
for (Type ty : pts.possibleTypes()) {
ofcgb.addBaseType(base, momc.context(), ty);
}
}
}
List<Local> argArrays = ofcgb.methodToInvokeBases().get(momc.method());
if (argArrays != null) {
for (final Local argArray : argArrays) {
PointsToSet pts = pa.reachingObjects(argArray);
if (pts instanceof PointsToSetInternal) {
PointsToSetInternal ptsi = (PointsToSetInternal) pts;
ptsi.forall(new P2SetVisitor() {
@Override
public void visit(Node n) {
assert n instanceof AllocNode;
AllocNode an = (AllocNode) n;
Object newExpr = an.getNewExpr();
ofcgb.addInvokeArgDotField(argArray, an.dot(ArrayElement.v()));
if (newExpr instanceof NewArrayExpr) {
NewArrayExpr nae = (NewArrayExpr) newExpr;
Value size = nae.getSize();
if (size instanceof IntConstant) {
IntConstant arrSize = (IntConstant) size;
ofcgb.addPossibleArgArraySize(argArray, arrSize.value, momc.context());
} else {
ofcgb.setArgArrayNonDetSize(argArray, momc.context());
}
}
}
});
}
for (Type t : pa.reachingObjectsOfArrayElement(pts).possibleTypes()) {
ofcgb.addInvokeArgType(argArray, momc.context(), t);
}
}
}
List<Local> stringConstants = ofcgb.methodToStringConstants().get(momc.method());
if (stringConstants != null)
for (Iterator<Local> stringConstantIt = stringConstants.iterator(); stringConstantIt.hasNext(); ) {
final Local stringConstant = stringConstantIt.next();
PointsToSet p2set = pa.reachingObjects(stringConstant);
Collection<String> possibleStringConstants = p2set.possibleStringConstants();
if (possibleStringConstants == null) {
ofcgb.addStringConstant(stringConstant, momc.context(), null);
} else {
for (Iterator<String> constantIt = possibleStringConstants.iterator(); constantIt.hasNext(); ) {
final String constant = constantIt.next();
ofcgb.addStringConstant(stringConstant, momc.context(), constant);
}
}
}
}
}
use of soot.jimple.spark.sets.P2SetVisitor in project soot by Sable.
the class StartJoinAnalysis method getMayAliasList.
private List<AllocNode> getMayAliasList(PointsToSetInternal pts) {
List<AllocNode> list = new ArrayList<AllocNode>();
final HashSet<AllocNode> ret = new HashSet<AllocNode>();
pts.forall(new P2SetVisitor() {
public void visit(Node n) {
ret.add((AllocNode) n);
}
});
Iterator<AllocNode> it = ret.iterator();
while (it.hasNext()) {
list.add(it.next());
}
return list;
}
Aggregations