use of soot.PointsToSet in project soot by Sable.
the class MethodRWSet method union.
/**
* Adds the RWSet other into this set.
*/
public boolean union(RWSet other) {
if (other == null)
return false;
if (isFull)
return false;
boolean ret = false;
if (other instanceof MethodRWSet) {
MethodRWSet o = (MethodRWSet) other;
if (o.getCallsNative()) {
ret = !getCallsNative() | ret;
setCallsNative();
}
if (o.isFull) {
ret = !isFull | ret;
isFull = true;
if (true)
throw new RuntimeException("attempt to add full set " + o + " into " + this);
globals = null;
fields = null;
return ret;
}
if (o.globals != null) {
if (globals == null)
globals = new HashSet();
ret = globals.addAll(o.globals) | ret;
if (globals.size() > MAX_SIZE) {
globals = null;
isFull = true;
throw new RuntimeException("attempt to add full set " + o + " into " + this);
}
}
if (o.fields != null) {
for (Object element : o.fields.keySet()) {
final Object field = element;
PointsToSet os = o.getBaseForField(field);
ret = addFieldRef(os, field) | ret;
}
}
} else {
StmtRWSet oth = (StmtRWSet) other;
if (oth.base != null) {
ret = addFieldRef(oth.base, oth.field) | ret;
} else if (oth.field != null) {
ret = addGlobal((SootField) oth.field) | ret;
}
}
if (!getCallsNative() && other.getCallsNative()) {
setCallsNative();
return true;
}
return ret;
}
use of soot.PointsToSet 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.PointsToSet 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();
}
};
}
use of soot.PointsToSet in project soot by Sable.
the class SideEffectAnalysis method addValue.
protected RWSet addValue(Value v, SootMethod m, Stmt s) {
RWSet ret = null;
if (v instanceof InstanceFieldRef) {
InstanceFieldRef ifr = (InstanceFieldRef) v;
PointsToSet base = pa.reachingObjects((Local) ifr.getBase());
ret = new StmtRWSet();
ret.addFieldRef(base, ifr.getField());
} else if (v instanceof StaticFieldRef) {
StaticFieldRef sfr = (StaticFieldRef) v;
ret = new StmtRWSet();
ret.addGlobal(sfr.getField());
} else if (v instanceof ArrayRef) {
ArrayRef ar = (ArrayRef) v;
PointsToSet base = pa.reachingObjects((Local) ar.getBase());
ret = new StmtRWSet();
ret.addFieldRef(base, PointsToAnalysis.ARRAY_ELEMENTS_NODE);
}
return ret;
}
use of soot.PointsToSet in project soot by Sable.
the class SiteRWSet method getBaseForField.
/**
* Returns a set of base objects whose field f is read/written.
*/
public PointsToSet getBaseForField(Object f) {
Union ret = null;
for (RWSet s : sets) {
PointsToSet os = s.getBaseForField(f);
if (os == null)
continue;
if (os.isEmpty())
continue;
if (ret == null)
ret = G.v().Union_factory.newUnion();
ret.addAll(os);
}
return ret;
}
Aggregations