Search in sources :

Example 11 with PointsToSet

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;
}
Also used : PointsToSet(soot.PointsToSet) SootField(soot.SootField) HashSet(java.util.HashSet)

Example 12 with PointsToSet

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);
                    }
                }
            }
    }
}
Also used : PointsToSet(soot.PointsToSet) PointsToSetInternal(soot.jimple.spark.sets.PointsToSetInternal) Node(soot.jimple.spark.pag.Node) AllocNode(soot.jimple.spark.pag.AllocNode) Local(soot.Local) Type(soot.Type) AllocNode(soot.jimple.spark.pag.AllocNode) NewArrayExpr(soot.jimple.NewArrayExpr) Iterator(java.util.Iterator) Value(soot.Value) IntConstant(soot.jimple.IntConstant) Collection(java.util.Collection) MethodOrMethodContext(soot.MethodOrMethodContext) P2SetVisitor(soot.jimple.spark.sets.P2SetVisitor)

Example 13 with PointsToSet

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();
        }
    };
}
Also used : LinkedHashSet(java.util.LinkedHashSet) PointsToSet(soot.PointsToSet) LinkedHashSet(java.util.LinkedHashSet) Set(java.util.Set) Constant(soot.jimple.Constant) ArrayList(java.util.ArrayList) Unit(soot.Unit) FlowFunctions(heros.FlowFunctions) ReturnStmt(soot.jimple.ReturnStmt) Stmt(soot.jimple.Stmt) DefinitionStmt(soot.jimple.DefinitionStmt) ArrayRef(soot.jimple.ArrayRef) InvokeExpr(soot.jimple.InvokeExpr) InstanceFieldRef(soot.jimple.InstanceFieldRef) PrimType(soot.PrimType) PointsToAnalysis(soot.PointsToAnalysis) Pair(soot.toolkits.scalar.Pair) PointsToSet(soot.PointsToSet) FlowFunction(heros.FlowFunction) Local(soot.Local) UnknownType(soot.UnknownType) Type(soot.Type) PrimType(soot.PrimType) ArrayRef(soot.jimple.ArrayRef) Ref(soot.jimple.Ref) InstanceFieldRef(soot.jimple.InstanceFieldRef) Value(soot.Value) NewExpr(soot.jimple.NewExpr) SootMethod(soot.SootMethod) DefinitionStmt(soot.jimple.DefinitionStmt) ReturnStmt(soot.jimple.ReturnStmt)

Example 14 with PointsToSet

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;
}
Also used : ArrayRef(soot.jimple.ArrayRef) PointsToSet(soot.PointsToSet) InstanceFieldRef(soot.jimple.InstanceFieldRef) StaticFieldRef(soot.jimple.StaticFieldRef)

Example 15 with PointsToSet

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;
}
Also used : PointsToSet(soot.PointsToSet)

Aggregations

PointsToSet (soot.PointsToSet)17 Local (soot.Local)5 EqualsSupportingPointsToSet (soot.jimple.spark.sets.EqualsSupportingPointsToSet)5 EmptyPointsToSet (soot.jimple.spark.sets.EmptyPointsToSet)4 HybridPointsToSet (soot.jimple.spark.sets.HybridPointsToSet)4 HashMap (java.util.HashMap)3 Iterator (java.util.Iterator)3 Map (java.util.Map)2 SootField (soot.SootField)2 Type (soot.Type)2 Value (soot.Value)2 ArrayRef (soot.jimple.ArrayRef)2 InstanceFieldRef (soot.jimple.InstanceFieldRef)2 FlowFunction (heros.FlowFunction)1 FlowFunctions (heros.FlowFunctions)1 ArrayList (java.util.ArrayList)1 Collection (java.util.Collection)1 HashSet (java.util.HashSet)1 LinkedHashSet (java.util.LinkedHashSet)1 Set (java.util.Set)1