Search in sources :

Example 1 with InstanceInvokeExpr

use of soot.jimple.InstanceInvokeExpr in project robovm by robovm.

the class MethodCompiler method invokeExpr.

private Value invokeExpr(Stmt stmt, InvokeExpr expr) {
    SootMethodRef methodRef = expr.getMethodRef();
    ArrayList<Value> args = new ArrayList<Value>();
    args.add(env);
    if (!(expr instanceof StaticInvokeExpr)) {
        Value base = immediate(stmt, (Immediate) ((InstanceInvokeExpr) expr).getBase());
        checkNull(stmt, base);
        args.add(base);
    }
    int i = 0;
    for (soot.Value sootArg : (List<soot.Value>) expr.getArgs()) {
        Value arg = immediate(stmt, (Immediate) sootArg);
        args.add(narrowFromI32Value(stmt, getType(methodRef.parameterType(i)), arg));
        i++;
    }
    Value result = null;
    FunctionRef functionRef = config.isDebug() ? null : Intrinsics.getIntrinsic(sootMethod, stmt, expr);
    if (functionRef == null) {
        Trampoline trampoline = null;
        String targetClassName = getInternalName(methodRef.declaringClass());
        String methodName = methodRef.name();
        String methodDesc = getDescriptor(methodRef);
        if (expr instanceof SpecialInvokeExpr) {
            soot.Type runtimeType = ((SpecialInvokeExpr) expr).getBase().getType();
            String runtimeClassName = runtimeType == NullType.v() ? targetClassName : getInternalName(runtimeType);
            trampoline = new Invokespecial(this.className, targetClassName, methodName, methodDesc, runtimeClassName);
        } else if (expr instanceof StaticInvokeExpr) {
            trampoline = new Invokestatic(this.className, targetClassName, methodName, methodDesc);
        } else if (expr instanceof VirtualInvokeExpr) {
            soot.Type runtimeType = ((VirtualInvokeExpr) expr).getBase().getType();
            String runtimeClassName = runtimeType == NullType.v() ? targetClassName : getInternalName(runtimeType);
            trampoline = new Invokevirtual(this.className, targetClassName, methodName, methodDesc, runtimeClassName);
        } else if (expr instanceof InterfaceInvokeExpr) {
            trampoline = new Invokeinterface(this.className, targetClassName, methodName, methodDesc);
        }
        trampolines.add(trampoline);
        if (canCallDirectly(expr)) {
            SootMethod method = this.sootMethod.getDeclaringClass().getMethod(methodRef.name(), methodRef.parameterTypes(), methodRef.returnType());
            if (method.isSynchronized()) {
                functionRef = FunctionBuilder.synchronizedWrapper(method).ref();
            } else {
                functionRef = createMethodFunction(method).ref();
            }
        } else {
            functionRef = trampoline.getFunctionRef();
        }
    }
    result = call(stmt, functionRef, args.toArray(new Value[0]));
    if (result != null) {
        return widenToI32Value(stmt, result, methodRef.returnType().equals(CharType.v()));
    } else {
        return null;
    }
}
Also used : Trampoline(org.robovm.compiler.trampoline.Trampoline) SootMethodRef(soot.SootMethodRef) SpecialInvokeExpr(soot.jimple.SpecialInvokeExpr) ArrayList(java.util.ArrayList) InstanceInvokeExpr(soot.jimple.InstanceInvokeExpr) InterfaceInvokeExpr(soot.jimple.InterfaceInvokeExpr) Invokeinterface(org.robovm.compiler.trampoline.Invokeinterface) Invokespecial(org.robovm.compiler.trampoline.Invokespecial) StaticInvokeExpr(soot.jimple.StaticInvokeExpr) Invokestatic(org.robovm.compiler.trampoline.Invokestatic) Value(org.robovm.compiler.llvm.Value) SootMethod(soot.SootMethod) ArrayList(java.util.ArrayList) List(java.util.List) VirtualInvokeExpr(soot.jimple.VirtualInvokeExpr) Invokevirtual(org.robovm.compiler.trampoline.Invokevirtual) FunctionRef(org.robovm.compiler.llvm.FunctionRef)

Example 2 with InstanceInvokeExpr

use of soot.jimple.InstanceInvokeExpr in project soot by Sable.

the class GeomPointsTo method preprocess.

/**
 *	Read in the program facts generated by SPARK.
 *  We also construct our own call graph and pointer variables.
 */
private void preprocess() {
    int id;
    int s, t;
    // Build the call graph
    n_func = Scene.v().getReachableMethods().size() + 1;
    call_graph = new CgEdge[n_func];
    n_calls = 0;
    n_reach_spark_user_methods = 0;
    id = 1;
    QueueReader<MethodOrMethodContext> smList = Scene.v().getReachableMethods().listener();
    CallGraph soot_callgraph = Scene.v().getCallGraph();
    while (smList.hasNext()) {
        final SootMethod func = smList.next().method();
        func2int.put(func, id);
        int2func.put(id, func);
        /*
			 * We cannot identify all entry methods since some entry methods call themselves.
			 * In that case, the Soot CallGraph.isEntryMethod() function returns false.
			 */
        if (soot_callgraph.isEntryMethod(func) || func.isEntryMethod()) {
            CgEdge p = new CgEdge(Constants.SUPER_MAIN, id, null, call_graph[Constants.SUPER_MAIN]);
            call_graph[Constants.SUPER_MAIN] = p;
            n_calls++;
        }
        if (!func.isJavaLibraryMethod())
            ++n_reach_spark_user_methods;
        id++;
    }
    // Next, we scan all the call edges and rebuild the call graph in our own vocabulary
    QueueReader<Edge> edgeList = Scene.v().getCallGraph().listener();
    while (edgeList.hasNext()) {
        Edge edge = edgeList.next();
        if (edge.isClinit()) {
            continue;
        }
        SootMethod src_func = edge.src();
        SootMethod tgt_func = edge.tgt();
        s = func2int.get(src_func);
        t = func2int.get(tgt_func);
        // Create a new call edge in our own format
        CgEdge p = new CgEdge(s, t, edge, call_graph[s]);
        call_graph[s] = p;
        edgeMapping.put(edge, p);
        // We collect callsite information
        Stmt callsite = edge.srcStmt();
        if (edge.isThreadRunCall() || edge.kind().isExecutor() || edge.kind().isAsyncTask()) {
            // We don't modify the treatment to the thread run() calls
            thread_run_callsites.add(callsite);
        } else if (edge.isInstance() && !edge.isSpecial()) {
            // We try to refine the virtual callsites (virtual + interface) with multiple call targets
            InstanceInvokeExpr expr = (InstanceInvokeExpr) callsite.getInvokeExpr();
            if (expr.getMethodRef().getSignature().contains("<java.lang.Thread: void start()>")) {
                // It is a thread start function
                thread_run_callsites.add(callsite);
            } else {
                p.base_var = findLocalVarNode(expr.getBase());
                if (SootInfo.countCallEdgesForCallsite(callsite, true) > 1 && p.base_var != null) {
                    multiCallsites.add(callsite);
                }
            }
        }
        ++n_calls;
    }
    // We build the wrappers for all the pointers built by SPARK
    for (Iterator<VarNode> it = getVarNodeNumberer().iterator(); it.hasNext(); ) {
        VarNode vn = it.next();
        IVarAbstraction pn = makeInternalNode(vn);
        pointers.add(pn);
    }
    for (Iterator<AllocDotField> it = getAllocDotFieldNodeNumberer().iterator(); it.hasNext(); ) {
        AllocDotField adf = it.next();
        // Some allocdotfield is invalid, we check and remove them
        SparkField field = adf.getField();
        if (field instanceof SootField) {
            // This is an instance field of a class
            Type decType = ((SootField) field).getDeclaringClass().getType();
            Type baseType = adf.getBase().getType();
            // baseType must be a sub type of decType
            if (!castNeverFails(baseType, decType))
                continue;
        }
        IVarAbstraction pn = makeInternalNode(adf);
        pointers.add(pn);
    }
    for (Iterator<AllocNode> it = getAllocNodeNumberer().iterator(); it.hasNext(); ) {
        AllocNode obj = it.next();
        IVarAbstraction pn = makeInternalNode(obj);
        allocations.add(pn);
    }
    // The address constraints, new obj -> p
    for (Object object : allocSources()) {
        IVarAbstraction obj = makeInternalNode((AllocNode) object);
        Node[] succs = allocLookup((AllocNode) object);
        for (Node element0 : succs) {
            PlainConstraint cons = new PlainConstraint();
            IVarAbstraction p = makeInternalNode(element0);
            cons.expr.setPair(obj, p);
            cons.type = Constants.NEW_CONS;
            constraints.add(cons);
        }
    }
    // The assign constraints, p -> q
    Pair<Node, Node> intercall = new Pair<Node, Node>();
    for (Object object : simpleSources()) {
        IVarAbstraction p = makeInternalNode((VarNode) object);
        Node[] succs = simpleLookup((VarNode) object);
        for (Node element0 : succs) {
            PlainConstraint cons = new PlainConstraint();
            IVarAbstraction q = makeInternalNode(element0);
            cons.expr.setPair(p, q);
            cons.type = Constants.ASSIGN_CONS;
            intercall.setPair((VarNode) object, element0);
            cons.interCallEdges = lookupEdgesForAssignment(intercall);
            constraints.add(cons);
        }
    }
    intercall = null;
    assign2edges.clear();
    // The load constraints, p.f -> q
    for (Object object : loadSources()) {
        FieldRefNode frn = (FieldRefNode) object;
        IVarAbstraction p = makeInternalNode(frn.getBase());
        Node[] succs = loadLookup(frn);
        for (Node element0 : succs) {
            PlainConstraint cons = new PlainConstraint();
            IVarAbstraction q = makeInternalNode(element0);
            cons.f = frn.getField();
            cons.expr.setPair(p, q);
            cons.type = Constants.LOAD_CONS;
            constraints.add(cons);
        }
    }
    // The store constraints, p -> q.f
    for (Object object : storeSources()) {
        IVarAbstraction p = makeInternalNode((VarNode) object);
        Node[] succs = storeLookup((VarNode) object);
        for (Node element0 : succs) {
            PlainConstraint cons = new PlainConstraint();
            FieldRefNode frn = (FieldRefNode) element0;
            IVarAbstraction q = makeInternalNode(frn.getBase());
            cons.f = frn.getField();
            cons.expr.setPair(p, q);
            cons.type = Constants.STORE_CONS;
            constraints.add(cons);
        }
    }
    n_init_constraints = constraints.size();
    // Initialize other stuff
    low_cg = new int[n_func];
    vis_cg = new int[n_func];
    rep_cg = new int[n_func];
    indeg_cg = new int[n_func];
    scc_size = new int[n_func];
    block_num = new int[n_func];
    context_size = new long[n_func];
    max_context_size_block = new long[n_func];
}
Also used : CgEdge(soot.jimple.spark.geom.dataRep.CgEdge) AllocDotField(soot.jimple.spark.pag.AllocDotField) PlainConstraint(soot.jimple.spark.geom.dataRep.PlainConstraint) SparkField(soot.jimple.spark.pag.SparkField) FieldRefNode(soot.jimple.spark.pag.FieldRefNode) ContextVarNode(soot.jimple.spark.pag.ContextVarNode) LocalVarNode(soot.jimple.spark.pag.LocalVarNode) Node(soot.jimple.spark.pag.Node) VarNode(soot.jimple.spark.pag.VarNode) AllocNode(soot.jimple.spark.pag.AllocNode) Stmt(soot.jimple.Stmt) MethodOrMethodContext(soot.MethodOrMethodContext) Pair(soot.toolkits.scalar.Pair) ContextVarNode(soot.jimple.spark.pag.ContextVarNode) LocalVarNode(soot.jimple.spark.pag.LocalVarNode) VarNode(soot.jimple.spark.pag.VarNode) InstanceInvokeExpr(soot.jimple.InstanceInvokeExpr) PlainConstraint(soot.jimple.spark.geom.dataRep.PlainConstraint) RefType(soot.RefType) Type(soot.Type) FieldRefNode(soot.jimple.spark.pag.FieldRefNode) CallGraph(soot.jimple.toolkits.callgraph.CallGraph) AllocNode(soot.jimple.spark.pag.AllocNode) SootMethod(soot.SootMethod) SootField(soot.SootField) Edge(soot.jimple.toolkits.callgraph.Edge) CgEdge(soot.jimple.spark.geom.dataRep.CgEdge)

Example 3 with InstanceInvokeExpr

use of soot.jimple.InstanceInvokeExpr in project soot by Sable.

the class GeomPointsTo method getCallTargets.

/**
 * Obtain the set of possible call targets at given @param callsite.
 */
private void getCallTargets(IVarAbstraction pn, SootMethod src, Stmt callsite, ChunkedQueue<SootMethod> targetsQueue) {
    InstanceInvokeExpr iie = (InstanceInvokeExpr) callsite.getInvokeExpr();
    Local receiver = (Local) iie.getBase();
    NumberedString subSig = iie.getMethodRef().getSubSignature();
    // We first build the set of possible call targets
    for (AllocNode an : pn.get_all_points_to_objects()) {
        Type type = an.getType();
        if (type == null)
            continue;
        VirtualCalls.v().resolve(type, receiver.getType(), subSig, src, targetsQueue);
    }
}
Also used : NumberedString(soot.util.NumberedString) RefType(soot.RefType) Type(soot.Type) AllocNode(soot.jimple.spark.pag.AllocNode) InstanceInvokeExpr(soot.jimple.InstanceInvokeExpr) Local(soot.Local)

Example 4 with InstanceInvokeExpr

use of soot.jimple.InstanceInvokeExpr in project soot by Sable.

the class AsmMethodSource method convertMethodInsn.

private void convertMethodInsn(MethodInsnNode insn) {
    int op = insn.getOpcode();
    boolean instance = op != INVOKESTATIC;
    StackFrame frame = getFrame(insn);
    Operand[] out = frame.out();
    Operand opr;
    Type returnType;
    if (out == null) {
        String clsName = AsmUtil.toQualifiedName(insn.owner);
        if (clsName.charAt(0) == '[')
            clsName = "java.lang.Object";
        SootClass cls = Scene.v().getSootClass(clsName);
        List<Type> sigTypes = AsmUtil.toJimpleDesc(insn.desc);
        returnType = sigTypes.remove(sigTypes.size() - 1);
        SootMethodRef ref = Scene.v().makeMethodRef(cls, insn.name, sigTypes, returnType, !instance);
        int nrArgs = sigTypes.size();
        final Operand[] args;
        List<Value> argList = Collections.emptyList();
        if (!instance) {
            args = nrArgs == 0 ? null : new Operand[nrArgs];
            if (args != null)
                argList = new ArrayList<Value>(nrArgs);
        } else {
            args = new Operand[nrArgs + 1];
            if (nrArgs != 0)
                argList = new ArrayList<Value>(nrArgs);
        }
        while (nrArgs-- != 0) {
            args[nrArgs] = popImmediate(sigTypes.get(nrArgs));
            argList.add(args[nrArgs].stackOrValue());
        }
        if (argList.size() > 1)
            Collections.reverse(argList);
        if (instance)
            args[args.length - 1] = popLocal();
        ValueBox[] boxes = args == null ? null : new ValueBox[args.length];
        InvokeExpr invoke;
        if (!instance) {
            invoke = Jimple.v().newStaticInvokeExpr(ref, argList);
        } else {
            Local base = (Local) args[args.length - 1].stackOrValue();
            InstanceInvokeExpr iinvoke;
            if (op == INVOKESPECIAL)
                iinvoke = Jimple.v().newSpecialInvokeExpr(base, ref, argList);
            else if (op == INVOKEVIRTUAL)
                iinvoke = Jimple.v().newVirtualInvokeExpr(base, ref, argList);
            else if (op == INVOKEINTERFACE)
                iinvoke = Jimple.v().newInterfaceInvokeExpr(base, ref, argList);
            else
                throw new AssertionError("Unknown invoke op:" + op);
            boxes[boxes.length - 1] = iinvoke.getBaseBox();
            args[args.length - 1].addBox(boxes[boxes.length - 1]);
            invoke = iinvoke;
        }
        if (boxes != null) {
            for (int i = 0; i != sigTypes.size(); i++) {
                boxes[i] = invoke.getArgBox(i);
                args[i].addBox(boxes[i]);
            }
            frame.boxes(boxes);
            frame.in(args);
        }
        opr = new Operand(insn, invoke);
        frame.out(opr);
    } else {
        opr = out[0];
        InvokeExpr expr = (InvokeExpr) opr.value;
        List<Type> types = expr.getMethodRef().parameterTypes();
        Operand[] oprs;
        int nrArgs = types.size();
        if (expr.getMethodRef().isStatic())
            oprs = nrArgs == 0 ? null : new Operand[nrArgs];
        else
            oprs = new Operand[nrArgs + 1];
        if (oprs != null) {
            while (nrArgs-- != 0) {
                oprs[nrArgs] = pop(types.get(nrArgs));
            }
            if (!expr.getMethodRef().isStatic())
                oprs[oprs.length - 1] = pop();
            frame.mergeIn(oprs);
            nrArgs = types.size();
        }
        returnType = expr.getMethodRef().returnType();
    }
    if (AsmUtil.isDWord(returnType))
        pushDual(opr);
    else if (!(returnType instanceof VoidType))
        push(opr);
    else if (!units.containsKey(insn))
        setUnit(insn, Jimple.v().newInvokeStmt(opr.value));
    /*
		 * assign all read ops in case the method modifies any of the fields
		 */
    assignReadOps(null);
}
Also used : VoidType(soot.VoidType) SootMethodRef(soot.SootMethodRef) ArrayList(java.util.ArrayList) Local(soot.Local) InstanceInvokeExpr(soot.jimple.InstanceInvokeExpr) SootClass(soot.SootClass) BooleanType(soot.BooleanType) Type(soot.Type) UnknownType(soot.UnknownType) ArrayType(soot.ArrayType) RefType(soot.RefType) ShortType(soot.ShortType) ByteType(soot.ByteType) DoubleType(soot.DoubleType) FloatType(soot.FloatType) IntType(soot.IntType) CharType(soot.CharType) LongType(soot.LongType) VoidType(soot.VoidType) DynamicInvokeExpr(soot.jimple.DynamicInvokeExpr) InstanceInvokeExpr(soot.jimple.InstanceInvokeExpr) InvokeExpr(soot.jimple.InvokeExpr) ValueBox(soot.ValueBox) Value(soot.Value)

Example 5 with InstanceInvokeExpr

use of soot.jimple.InstanceInvokeExpr in project soot by Sable.

the class PAG method addCallTarget.

public final void addCallTarget(Edge e) {
    if (!e.passesParameters())
        return;
    MethodPAG srcmpag = MethodPAG.v(this, e.src());
    MethodPAG tgtmpag = MethodPAG.v(this, e.tgt());
    Pair<Node, Node> pval;
    if (e.isExplicit() || e.kind() == Kind.THREAD || e.kind() == Kind.ASYNCTASK) {
        addCallTarget(srcmpag, tgtmpag, (Stmt) e.srcUnit(), e.srcCtxt(), e.tgtCtxt(), e);
    } else if (e.kind() == Kind.EXECUTOR) {
        InvokeExpr ie = e.srcStmt().getInvokeExpr();
        boolean virtualCall = callAssigns.containsKey(ie);
        Node parm = srcmpag.nodeFactory().getNode(ie.getArg(0));
        parm = srcmpag.parameterize(parm, e.srcCtxt());
        parm = parm.getReplacement();
        Node thiz = tgtmpag.nodeFactory().caseThis();
        thiz = tgtmpag.parameterize(thiz, e.tgtCtxt());
        thiz = thiz.getReplacement();
        addEdge(parm, thiz);
        pval = addInterproceduralAssignment(parm, thiz, e);
        callAssigns.put(ie, pval);
        callToMethod.put(ie, srcmpag.getMethod());
        if (virtualCall && !virtualCallsToReceivers.containsKey(ie)) {
            virtualCallsToReceivers.put(ie, parm);
        }
    } else if (e.kind() == Kind.HANDLER) {
        InvokeExpr ie = e.srcStmt().getInvokeExpr();
        boolean virtualCall = callAssigns.containsKey(ie);
        assert virtualCall == true;
        Node base = srcmpag.nodeFactory().getNode(((VirtualInvokeExpr) ie).getBase());
        base = srcmpag.parameterize(base, e.srcCtxt());
        base = base.getReplacement();
        Node thiz = tgtmpag.nodeFactory().caseThis();
        thiz = tgtmpag.parameterize(thiz, e.tgtCtxt());
        thiz = thiz.getReplacement();
        addEdge(base, thiz);
        pval = addInterproceduralAssignment(base, thiz, e);
        callAssigns.put(ie, pval);
        callToMethod.put(ie, srcmpag.getMethod());
        virtualCallsToReceivers.put(ie, base);
    } else if (e.kind() == Kind.PRIVILEGED) {
        // Flow from first parameter of doPrivileged() invocation
        // to this of target, and from return of target to the
        // return of doPrivileged()
        InvokeExpr ie = e.srcStmt().getInvokeExpr();
        Node parm = srcmpag.nodeFactory().getNode(ie.getArg(0));
        parm = srcmpag.parameterize(parm, e.srcCtxt());
        parm = parm.getReplacement();
        Node thiz = tgtmpag.nodeFactory().caseThis();
        thiz = tgtmpag.parameterize(thiz, e.tgtCtxt());
        thiz = thiz.getReplacement();
        addEdge(parm, thiz);
        pval = addInterproceduralAssignment(parm, thiz, e);
        callAssigns.put(ie, pval);
        callToMethod.put(ie, srcmpag.getMethod());
        if (e.srcUnit() instanceof AssignStmt) {
            AssignStmt as = (AssignStmt) e.srcUnit();
            Node ret = tgtmpag.nodeFactory().caseRet();
            ret = tgtmpag.parameterize(ret, e.tgtCtxt());
            ret = ret.getReplacement();
            Node lhs = srcmpag.nodeFactory().getNode(as.getLeftOp());
            lhs = srcmpag.parameterize(lhs, e.srcCtxt());
            lhs = lhs.getReplacement();
            addEdge(ret, lhs);
            pval = addInterproceduralAssignment(ret, lhs, e);
            callAssigns.put(ie, pval);
            callToMethod.put(ie, srcmpag.getMethod());
        }
    } else if (e.kind() == Kind.FINALIZE) {
        Node srcThis = srcmpag.nodeFactory().caseThis();
        srcThis = srcmpag.parameterize(srcThis, e.srcCtxt());
        srcThis = srcThis.getReplacement();
        Node tgtThis = tgtmpag.nodeFactory().caseThis();
        tgtThis = tgtmpag.parameterize(tgtThis, e.tgtCtxt());
        tgtThis = tgtThis.getReplacement();
        addEdge(srcThis, tgtThis);
        pval = addInterproceduralAssignment(srcThis, tgtThis, e);
    } else if (e.kind() == Kind.NEWINSTANCE) {
        Stmt s = (Stmt) e.srcUnit();
        InstanceInvokeExpr iie = (InstanceInvokeExpr) s.getInvokeExpr();
        Node cls = srcmpag.nodeFactory().getNode(iie.getBase());
        cls = srcmpag.parameterize(cls, e.srcCtxt());
        cls = cls.getReplacement();
        Node newObject = nodeFactory.caseNewInstance((VarNode) cls);
        Node initThis = tgtmpag.nodeFactory().caseThis();
        initThis = tgtmpag.parameterize(initThis, e.tgtCtxt());
        initThis = initThis.getReplacement();
        addEdge(newObject, initThis);
        if (s instanceof AssignStmt) {
            AssignStmt as = (AssignStmt) s;
            Node asLHS = srcmpag.nodeFactory().getNode(as.getLeftOp());
            asLHS = srcmpag.parameterize(asLHS, e.srcCtxt());
            asLHS = asLHS.getReplacement();
            addEdge(newObject, asLHS);
        }
        pval = addInterproceduralAssignment(newObject, initThis, e);
        callAssigns.put(s.getInvokeExpr(), pval);
        callToMethod.put(s.getInvokeExpr(), srcmpag.getMethod());
    } else if (e.kind() == Kind.REFL_INVOKE) {
        // Flow (1) from first parameter of invoke(..) invocation
        // to this of target, (2) from the contents of the second (array)
        // parameter
        // to all parameters of the target, and (3) from return of target to
        // the
        // return of invoke(..)
        // (1)
        InvokeExpr ie = e.srcStmt().getInvokeExpr();
        Value arg0 = ie.getArg(0);
        // if "null" is passed in, omit the edge
        if (arg0 != NullConstant.v()) {
            Node parm0 = srcmpag.nodeFactory().getNode(arg0);
            parm0 = srcmpag.parameterize(parm0, e.srcCtxt());
            parm0 = parm0.getReplacement();
            Node thiz = tgtmpag.nodeFactory().caseThis();
            thiz = tgtmpag.parameterize(thiz, e.tgtCtxt());
            thiz = thiz.getReplacement();
            addEdge(parm0, thiz);
            pval = addInterproceduralAssignment(parm0, thiz, e);
            callAssigns.put(ie, pval);
            callToMethod.put(ie, srcmpag.getMethod());
        }
        // (2)
        Value arg1 = ie.getArg(1);
        SootMethod tgt = e.getTgt().method();
        // edge
        if (arg1 != NullConstant.v() && tgt.getParameterCount() > 0) {
            Node parm1 = srcmpag.nodeFactory().getNode(arg1);
            parm1 = srcmpag.parameterize(parm1, e.srcCtxt());
            parm1 = parm1.getReplacement();
            FieldRefNode parm1contents = makeFieldRefNode((VarNode) parm1, ArrayElement.v());
            for (int i = 0; i < tgt.getParameterCount(); i++) {
                // if no reference type, create no edge
                if (!(tgt.getParameterType(i) instanceof RefLikeType))
                    continue;
                Node tgtParmI = tgtmpag.nodeFactory().caseParm(i);
                tgtParmI = tgtmpag.parameterize(tgtParmI, e.tgtCtxt());
                tgtParmI = tgtParmI.getReplacement();
                addEdge(parm1contents, tgtParmI);
                pval = addInterproceduralAssignment(parm1contents, tgtParmI, e);
                callAssigns.put(ie, pval);
            }
        }
        // the return type of the callee is actually a reference type
        if (e.srcUnit() instanceof AssignStmt && (tgt.getReturnType() instanceof RefLikeType)) {
            AssignStmt as = (AssignStmt) e.srcUnit();
            Node ret = tgtmpag.nodeFactory().caseRet();
            ret = tgtmpag.parameterize(ret, e.tgtCtxt());
            ret = ret.getReplacement();
            Node lhs = srcmpag.nodeFactory().getNode(as.getLeftOp());
            lhs = srcmpag.parameterize(lhs, e.srcCtxt());
            lhs = lhs.getReplacement();
            addEdge(ret, lhs);
            pval = addInterproceduralAssignment(ret, lhs, e);
            callAssigns.put(ie, pval);
        }
    } else if (e.kind() == Kind.REFL_CLASS_NEWINSTANCE || e.kind() == Kind.REFL_CONSTR_NEWINSTANCE) {
        // (1) create a fresh node for the new object
        // (2) create edge from this object to "this" of the constructor
        // (3) if this is a call to Constructor.newInstance and not
        // Class.newInstance,
        // create edges passing the contents of the arguments array of the
        // call
        // to all possible parameters of the target
        // (4) if we are inside an assign statement,
        // assign the fresh object from (1) to the LHS of the assign
        // statement
        Stmt s = (Stmt) e.srcUnit();
        InstanceInvokeExpr iie = (InstanceInvokeExpr) s.getInvokeExpr();
        // (1)
        Node cls = srcmpag.nodeFactory().getNode(iie.getBase());
        cls = srcmpag.parameterize(cls, e.srcCtxt());
        cls = cls.getReplacement();
        if (cls instanceof ContextVarNode)
            cls = findLocalVarNode(((VarNode) cls).getVariable());
        VarNode newObject = makeGlobalVarNode(cls, RefType.v("java.lang.Object"));
        SootClass tgtClass = e.getTgt().method().getDeclaringClass();
        RefType tgtType = tgtClass.getType();
        AllocNode site = makeAllocNode(new Pair<Node, SootClass>(cls, tgtClass), tgtType, null);
        addEdge(site, newObject);
        // (2)
        Node initThis = tgtmpag.nodeFactory().caseThis();
        initThis = tgtmpag.parameterize(initThis, e.tgtCtxt());
        initThis = initThis.getReplacement();
        addEdge(newObject, initThis);
        addInterproceduralAssignment(newObject, initThis, e);
        // (3)
        if (e.kind() == Kind.REFL_CONSTR_NEWINSTANCE) {
            Value arg = iie.getArg(0);
            SootMethod tgt = e.getTgt().method();
            // edge
            if (arg != NullConstant.v() && tgt.getParameterCount() > 0) {
                Node parm0 = srcmpag.nodeFactory().getNode(arg);
                parm0 = srcmpag.parameterize(parm0, e.srcCtxt());
                parm0 = parm0.getReplacement();
                FieldRefNode parm1contents = makeFieldRefNode((VarNode) parm0, ArrayElement.v());
                for (int i = 0; i < tgt.getParameterCount(); i++) {
                    // if no reference type, create no edge
                    if (!(tgt.getParameterType(i) instanceof RefLikeType))
                        continue;
                    Node tgtParmI = tgtmpag.nodeFactory().caseParm(i);
                    tgtParmI = tgtmpag.parameterize(tgtParmI, e.tgtCtxt());
                    tgtParmI = tgtParmI.getReplacement();
                    addEdge(parm1contents, tgtParmI);
                    pval = addInterproceduralAssignment(parm1contents, tgtParmI, e);
                    callAssigns.put(iie, pval);
                }
            }
        }
        // (4)
        if (s instanceof AssignStmt) {
            AssignStmt as = (AssignStmt) s;
            Node asLHS = srcmpag.nodeFactory().getNode(as.getLeftOp());
            asLHS = srcmpag.parameterize(asLHS, e.srcCtxt());
            asLHS = asLHS.getReplacement();
            addEdge(newObject, asLHS);
        }
        pval = addInterproceduralAssignment(newObject, initThis, e);
        callAssigns.put(s.getInvokeExpr(), pval);
        callToMethod.put(s.getInvokeExpr(), srcmpag.getMethod());
    } else {
        throw new RuntimeException("Unhandled edge " + e);
    }
}
Also used : AssignStmt(soot.jimple.AssignStmt) InstanceInvokeExpr(soot.jimple.InstanceInvokeExpr) SootClass(soot.SootClass) AssignStmt(soot.jimple.AssignStmt) Stmt(soot.jimple.Stmt) RefLikeType(soot.RefLikeType) RefType(soot.RefType) InstanceInvokeExpr(soot.jimple.InstanceInvokeExpr) VirtualInvokeExpr(soot.jimple.VirtualInvokeExpr) InvokeExpr(soot.jimple.InvokeExpr) Value(soot.Value) SootMethod(soot.SootMethod) Pair(soot.toolkits.scalar.Pair)

Aggregations

InstanceInvokeExpr (soot.jimple.InstanceInvokeExpr)25 Value (soot.Value)13 InvokeExpr (soot.jimple.InvokeExpr)13 Stmt (soot.jimple.Stmt)12 Local (soot.Local)11 RefType (soot.RefType)11 SootMethod (soot.SootMethod)10 Type (soot.Type)9 StaticInvokeExpr (soot.jimple.StaticInvokeExpr)9 ArrayList (java.util.ArrayList)8 SootClass (soot.SootClass)8 Unit (soot.Unit)8 AssignStmt (soot.jimple.AssignStmt)8 VirtualInvokeExpr (soot.jimple.VirtualInvokeExpr)8 SpecialInvokeExpr (soot.jimple.SpecialInvokeExpr)7 ValueBox (soot.ValueBox)6 InvokeStmt (soot.jimple.InvokeStmt)6 Iterator (java.util.Iterator)5 SootMethodRef (soot.SootMethodRef)5 InterfaceInvokeExpr (soot.jimple.InterfaceInvokeExpr)5