Search in sources :

Example 11 with IdentityStmt

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

the class ThisInliner method internalTransform.

public void internalTransform(Body b, String phaseName, Map options) {
    // assure body is a constructor
    if (!b.getMethod().getName().equals("<init>"))
        return;
    // if the first invoke is a this() and not a super() inline the this()
    InvokeStmt invokeStmt = getFirstSpecialInvoke(b);
    if (invokeStmt == null)
        return;
    SpecialInvokeExpr specInvokeExpr = (SpecialInvokeExpr) invokeStmt.getInvokeExpr();
    if (specInvokeExpr.getMethod().getDeclaringClass().equals(b.getMethod().getDeclaringClass())) {
        // put locals from inlinee into container
        if (!specInvokeExpr.getMethod().hasActiveBody()) {
            specInvokeExpr.getMethod().retrieveActiveBody();
        }
        HashMap<Local, Local> oldLocalsToNew = new HashMap<Local, Local>();
        for (Local l : specInvokeExpr.getMethod().getActiveBody().getLocals()) {
            Local newLocal = (Local) l.clone();
            b.getLocals().add(newLocal);
            oldLocalsToNew.put(l, newLocal);
        }
        // find identity stmt of original method
        IdentityStmt origIdStmt = findIdentityStmt(b);
        HashMap<Stmt, Stmt> oldStmtsToNew = new HashMap<Stmt, Stmt>();
        // System.out.println("locals: "+b.getLocals());
        Chain<Unit> containerUnits = b.getUnits();
        for (Unit u : specInvokeExpr.getMethod().getActiveBody().getUnits()) {
            Stmt inlineeStmt = (Stmt) u;
            // handle identity stmts
            if (inlineeStmt instanceof IdentityStmt) {
                IdentityStmt idStmt = (IdentityStmt) inlineeStmt;
                if (idStmt.getRightOp() instanceof ThisRef) {
                    Stmt newThis = Jimple.v().newAssignStmt((Local) oldLocalsToNew.get(idStmt.getLeftOp()), origIdStmt.getLeftOp());
                    containerUnits.insertBefore(newThis, invokeStmt);
                    oldStmtsToNew.put(inlineeStmt, newThis);
                } else if (idStmt.getRightOp() instanceof CaughtExceptionRef) {
                    Stmt newInlinee = (Stmt) inlineeStmt.clone();
                    for (ValueBox next : newInlinee.getUseAndDefBoxes()) {
                        if (next.getValue() instanceof Local) {
                            next.setValue((Local) oldLocalsToNew.get(next.getValue()));
                        }
                    }
                    containerUnits.insertBefore(newInlinee, invokeStmt);
                    oldStmtsToNew.put(inlineeStmt, newInlinee);
                } else if (idStmt.getRightOp() instanceof ParameterRef) {
                    Stmt newParam = Jimple.v().newAssignStmt((Local) oldLocalsToNew.get(idStmt.getLeftOp()), specInvokeExpr.getArg(((ParameterRef) idStmt.getRightOp()).getIndex()));
                    containerUnits.insertBefore(newParam, invokeStmt);
                    oldStmtsToNew.put(inlineeStmt, newParam);
                }
            } else // from a constructor)
            if (inlineeStmt instanceof ReturnVoidStmt) {
                Stmt newRet = Jimple.v().newGotoStmt((Stmt) containerUnits.getSuccOf(invokeStmt));
                containerUnits.insertBefore(newRet, invokeStmt);
                System.out.println("adding to stmt map: " + inlineeStmt + " and " + newRet);
                oldStmtsToNew.put(inlineeStmt, newRet);
            } else {
                Stmt newInlinee = (Stmt) inlineeStmt.clone();
                for (ValueBox next : newInlinee.getUseAndDefBoxes()) {
                    if (next.getValue() instanceof Local) {
                        next.setValue((Local) oldLocalsToNew.get(next.getValue()));
                    }
                }
                containerUnits.insertBefore(newInlinee, invokeStmt);
                oldStmtsToNew.put(inlineeStmt, newInlinee);
            }
        }
        // handleTraps
        for (Trap t : specInvokeExpr.getMethod().getActiveBody().getTraps()) {
            System.out.println("begin: " + t.getBeginUnit());
            Stmt newBegin = oldStmtsToNew.get(t.getBeginUnit());
            System.out.println("end: " + t.getEndUnit());
            Stmt newEnd = oldStmtsToNew.get(t.getEndUnit());
            System.out.println("handler: " + t.getHandlerUnit());
            Stmt newHandler = oldStmtsToNew.get(t.getHandlerUnit());
            if (newBegin == null || newEnd == null || newHandler == null)
                throw new RuntimeException("couldn't map trap!");
            b.getTraps().add(Jimple.v().newTrap(t.getException(), newBegin, newEnd, newHandler));
        }
        // patch gotos
        for (Unit u : specInvokeExpr.getMethod().getActiveBody().getUnits()) {
            Stmt inlineeStmt = (Stmt) u;
            if (inlineeStmt instanceof GotoStmt) {
                System.out.println("inlinee goto target: " + ((GotoStmt) inlineeStmt).getTarget());
                ((GotoStmt) oldStmtsToNew.get(inlineeStmt)).setTarget(oldStmtsToNew.get(((GotoStmt) inlineeStmt).getTarget()));
            }
        }
        // remove original invoke
        containerUnits.remove(invokeStmt);
        // resolve name collisions
        LocalNameStandardizer.v().transform(b, "ji.lns");
    }
// System.out.println("locals: "+b.getLocals());
// System.out.println("units: "+b.getUnits());
}
Also used : InvokeStmt(soot.jimple.InvokeStmt) CaughtExceptionRef(soot.jimple.CaughtExceptionRef) HashMap(java.util.HashMap) SpecialInvokeExpr(soot.jimple.SpecialInvokeExpr) ReturnVoidStmt(soot.jimple.ReturnVoidStmt) Local(soot.Local) Trap(soot.Trap) Unit(soot.Unit) GotoStmt(soot.jimple.GotoStmt) Stmt(soot.jimple.Stmt) ReturnVoidStmt(soot.jimple.ReturnVoidStmt) InvokeStmt(soot.jimple.InvokeStmt) IdentityStmt(soot.jimple.IdentityStmt) ParameterRef(soot.jimple.ParameterRef) ThisRef(soot.jimple.ThisRef) ValueBox(soot.ValueBox) GotoStmt(soot.jimple.GotoStmt) IdentityStmt(soot.jimple.IdentityStmt)

Example 12 with IdentityStmt

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

the class Body method getParameterRefs.

/**
 * Returns the list of parameter references used in this body. The list is as long as
 * the number of parameters declared in the associated method's signature.
 * The list may have <code>null</code> entries for parameters not referenced in the body.
 * The returned list is of fixed size.
 */
public List<Value> getParameterRefs() {
    Value[] res = new Value[getMethod().getParameterCount()];
    for (Unit s : getUnits()) {
        if (s instanceof IdentityStmt) {
            Value rightOp = ((IdentityStmt) s).getRightOp();
            if (rightOp instanceof ParameterRef) {
                ParameterRef parameterRef = (ParameterRef) rightOp;
                res[parameterRef.getIndex()] = parameterRef;
            }
        }
    }
    return Arrays.asList(res);
}
Also used : ParameterRef(soot.jimple.ParameterRef) IdentityStmt(soot.jimple.IdentityStmt)

Example 13 with IdentityStmt

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

the class Body method getParameterLocal.

/**
 * Return LHS of the first identity stmt assigning from \@parameter i. *
 */
public Local getParameterLocal(int i) {
    for (Unit s : getUnits()) {
        if (s instanceof IdentityStmt && ((IdentityStmt) s).getRightOp() instanceof ParameterRef) {
            IdentityStmt is = (IdentityStmt) s;
            ParameterRef pr = (ParameterRef) is.getRightOp();
            if (pr.getIndex() == i)
                return (Local) is.getLeftOp();
        }
    }
    throw new RuntimeException("couldn't find parameterref" + i + "! in " + getMethod());
}
Also used : ParameterRef(soot.jimple.ParameterRef) IdentityStmt(soot.jimple.IdentityStmt)

Example 14 with IdentityStmt

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

the class LibraryMethodWrappersBuilder method getFirstNotIdentityStmt.

private static Unit getFirstNotIdentityStmt(Body body) {
    final Iterator<Unit> unitIterator = body.getUnits().snapshotIterator();
    while (unitIterator.hasNext()) {
        final Unit unit = unitIterator.next();
        if (unit instanceof IdentityStmt) {
            continue;
        }
        return unit;
    }
    logger.debug("There are no non-identity units in the method body.");
    return null;
}
Also used : Unit(soot.Unit) IdentityStmt(soot.jimple.IdentityStmt)

Example 15 with IdentityStmt

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

the class StaticMethodBinder method internalTransform.

protected void internalTransform(String phaseName, Map opts) {
    Filter instanceInvokesFilter = new Filter(new InstanceInvokeEdgesPred());
    SMBOptions options = new SMBOptions(opts);
    String modifierOptions = PhaseOptions.getString(opts, "allowed-modifier-changes");
    HashMap instanceToStaticMap = new HashMap();
    CallGraph cg = Scene.v().getCallGraph();
    Hierarchy hierarchy = Scene.v().getActiveHierarchy();
    Iterator classesIt = Scene.v().getApplicationClasses().iterator();
    while (classesIt.hasNext()) {
        SootClass c = (SootClass) classesIt.next();
        LinkedList methodsList = new LinkedList();
        for (Iterator it = c.methodIterator(); it.hasNext(); ) {
            methodsList.add(it.next());
        }
        while (!methodsList.isEmpty()) {
            SootMethod container = (SootMethod) methodsList.removeFirst();
            if (!container.isConcrete())
                continue;
            if (!instanceInvokesFilter.wrap(cg.edgesOutOf(container)).hasNext())
                continue;
            JimpleBody b = (JimpleBody) container.getActiveBody();
            List<Unit> unitList = new ArrayList<Unit>();
            unitList.addAll(b.getUnits());
            Iterator<Unit> unitIt = unitList.iterator();
            while (unitIt.hasNext()) {
                Stmt s = (Stmt) unitIt.next();
                if (!s.containsInvokeExpr())
                    continue;
                InvokeExpr ie = s.getInvokeExpr();
                if (ie instanceof StaticInvokeExpr || ie instanceof SpecialInvokeExpr)
                    continue;
                Iterator targets = new Targets(instanceInvokesFilter.wrap(cg.edgesOutOf(s)));
                if (!targets.hasNext())
                    continue;
                SootMethod target = (SootMethod) targets.next();
                if (targets.hasNext())
                    continue;
                if (!AccessManager.ensureAccess(container, target, modifierOptions))
                    continue;
                if (!target.getDeclaringClass().isApplicationClass() || !target.isConcrete())
                    continue;
                // Don't modify java.lang.Object
                if (target.getDeclaringClass() == Scene.v().getSootClass("java.lang.Object"))
                    continue;
                if (!instanceToStaticMap.containsKey(target)) {
                    List newParameterTypes = new ArrayList();
                    newParameterTypes.add(RefType.v(target.getDeclaringClass().getName()));
                    newParameterTypes.addAll(target.getParameterTypes());
                    // Check for signature conflicts.
                    String newName = target.getName() + "_static";
                    while (target.getDeclaringClass().declaresMethod(newName, newParameterTypes, target.getReturnType())) newName = newName + "_static";
                    SootMethod ct = Scene.v().makeSootMethod(newName, newParameterTypes, target.getReturnType(), target.getModifiers() | Modifier.STATIC, target.getExceptions());
                    target.getDeclaringClass().addMethod(ct);
                    methodsList.addLast(ct);
                    ct.setActiveBody((Body) target.getActiveBody().clone());
                    // Make the invoke graph take into account the
                    // newly-cloned body.
                    {
                        Iterator oldUnits = target.getActiveBody().getUnits().iterator();
                        Iterator newUnits = ct.getActiveBody().getUnits().iterator();
                        while (newUnits.hasNext()) {
                            Stmt oldStmt, newStmt;
                            oldStmt = (Stmt) oldUnits.next();
                            newStmt = (Stmt) newUnits.next();
                            Iterator edges = cg.edgesOutOf(oldStmt);
                            while (edges.hasNext()) {
                                Edge e = (Edge) edges.next();
                                cg.addEdge(new Edge(ct, newStmt, e.tgt(), e.kind()));
                                cg.removeEdge(e);
                            }
                        }
                    }
                    // Shift the parameter list to apply to the new this
                    // parameter.
                    // If the method uses this, then we replace
                    // the r0 := @this with r0 := @parameter0 & shift.
                    // Otherwise, just zap the r0 := @this.
                    {
                        Body newBody = ct.getActiveBody();
                        Chain units = newBody.getUnits();
                        Iterator unitsIt = newBody.getUnits().snapshotIterator();
                        while (unitsIt.hasNext()) {
                            Stmt st = (Stmt) unitsIt.next();
                            if (st instanceof IdentityStmt) {
                                IdentityStmt is = (IdentityStmt) st;
                                if (is.getRightOp() instanceof ThisRef) {
                                    units.swapWith(st, Jimple.v().newIdentityStmt(is.getLeftOp(), Jimple.v().newParameterRef(is.getRightOp().getType(), 0)));
                                } else {
                                    if (is.getRightOp() instanceof ParameterRef) {
                                        ParameterRef ro = (ParameterRef) is.getRightOp();
                                        ro.setIndex(ro.getIndex() + 1);
                                    }
                                }
                            }
                        }
                    }
                    instanceToStaticMap.put(target, ct);
                }
                SootMethod clonedTarget = (SootMethod) instanceToStaticMap.get(target);
                Value thisToAdd = ((InstanceInvokeExpr) ie).getBase();
                // Insert casts to please the verifier.
                if (options.insert_redundant_casts()) {
                    // The verifier will complain if targetUsesThis, and:
                    // the argument passed to the method is not the same
                    // type.
                    // For instance, Bottle.price_static takes a cost.
                    // Cost is an interface implemented by Bottle.
                    SootClass localType, parameterType;
                    localType = ((RefType) ((InstanceInvokeExpr) ie).getBase().getType()).getSootClass();
                    parameterType = target.getDeclaringClass();
                    if (localType.isInterface() || hierarchy.isClassSuperclassOf(localType, parameterType)) {
                        Local castee = Jimple.v().newLocal("__castee", parameterType.getType());
                        b.getLocals().add(castee);
                        b.getUnits().insertBefore(Jimple.v().newAssignStmt(castee, Jimple.v().newCastExpr(((InstanceInvokeExpr) ie).getBase(), parameterType.getType())), s);
                        thisToAdd = castee;
                    }
                }
                // Now rebind the method call & fix the invoke graph.
                {
                    List newArgs = new ArrayList();
                    newArgs.add(thisToAdd);
                    newArgs.addAll(ie.getArgs());
                    StaticInvokeExpr sie = Jimple.v().newStaticInvokeExpr(clonedTarget.makeRef(), newArgs);
                    ValueBox ieBox = s.getInvokeExprBox();
                    ieBox.setValue(sie);
                    cg.addEdge(new Edge(container, s, clonedTarget));
                }
                // (If enabled), add a null pointer check.
                if (options.insert_null_checks()) {
                    boolean caught = TrapManager.isExceptionCaughtAt(Scene.v().getSootClass("java.lang.NullPointerException"), s, b);
                    /* Ah ha. Caught again! */
                    if (caught) {
                        /*
							 * In this case, we don't use throwPoint; instead,
							 * put the code right there.
							 */
                        Stmt insertee = Jimple.v().newIfStmt(Jimple.v().newNeExpr(((InstanceInvokeExpr) ie).getBase(), NullConstant.v()), s);
                        b.getUnits().insertBefore(insertee, s);
                        // This sucks (but less than before).
                        ((IfStmt) insertee).setTarget(s);
                        ThrowManager.addThrowAfter(b, insertee);
                    } else {
                        Stmt throwPoint = ThrowManager.getNullPointerExceptionThrower(b);
                        b.getUnits().insertBefore(Jimple.v().newIfStmt(Jimple.v().newEqExpr(((InstanceInvokeExpr) ie).getBase(), NullConstant.v()), throwPoint), s);
                    }
                }
                // Add synchronizing stuff.
                {
                    if (target.isSynchronized()) {
                        clonedTarget.setModifiers(clonedTarget.getModifiers() & ~Modifier.SYNCHRONIZED);
                        SynchronizerManager.v().synchronizeStmtOn(s, b, (Local) ((InstanceInvokeExpr) ie).getBase());
                    }
                }
                // Resolve name collisions.
                LocalNameStandardizer.v().transform(b, phaseName + ".lns");
            }
        }
    }
}
Also used : Chain(soot.util.Chain) HashMap(java.util.HashMap) SpecialInvokeExpr(soot.jimple.SpecialInvokeExpr) ArrayList(java.util.ArrayList) Unit(soot.Unit) IfStmt(soot.jimple.IfStmt) IdentityStmt(soot.jimple.IdentityStmt) Stmt(soot.jimple.Stmt) StaticInvokeExpr(soot.jimple.StaticInvokeExpr) Hierarchy(soot.Hierarchy) InstanceInvokeEdgesPred(soot.jimple.toolkits.callgraph.InstanceInvokeEdgesPred) InstanceInvokeExpr(soot.jimple.InstanceInvokeExpr) SpecialInvokeExpr(soot.jimple.SpecialInvokeExpr) StaticInvokeExpr(soot.jimple.StaticInvokeExpr) InvokeExpr(soot.jimple.InvokeExpr) Iterator(java.util.Iterator) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) List(java.util.List) JimpleBody(soot.jimple.JimpleBody) Body(soot.Body) JimpleBody(soot.jimple.JimpleBody) IdentityStmt(soot.jimple.IdentityStmt) SMBOptions(soot.options.SMBOptions) InstanceInvokeExpr(soot.jimple.InstanceInvokeExpr) Local(soot.Local) Targets(soot.jimple.toolkits.callgraph.Targets) SootClass(soot.SootClass) LinkedList(java.util.LinkedList) ParameterRef(soot.jimple.ParameterRef) IfStmt(soot.jimple.IfStmt) Filter(soot.jimple.toolkits.callgraph.Filter) CallGraph(soot.jimple.toolkits.callgraph.CallGraph) ThisRef(soot.jimple.ThisRef) ValueBox(soot.ValueBox) Value(soot.Value) SootMethod(soot.SootMethod) Edge(soot.jimple.toolkits.callgraph.Edge)

Aggregations

IdentityStmt (soot.jimple.IdentityStmt)25 Unit (soot.Unit)20 Local (soot.Local)14 Value (soot.Value)14 AssignStmt (soot.jimple.AssignStmt)13 InvokeExpr (soot.jimple.InvokeExpr)11 Type (soot.Type)10 ParameterRef (soot.jimple.ParameterRef)10 ReturnStmt (soot.jimple.ReturnStmt)10 IfStmt (soot.jimple.IfStmt)9 Stmt (soot.jimple.Stmt)9 ArrayList (java.util.ArrayList)8 InvokeStmt (soot.jimple.InvokeStmt)8 HashSet (java.util.HashSet)7 ArrayType (soot.ArrayType)7 RefType (soot.RefType)7 ArrayRef (soot.jimple.ArrayRef)7 CastExpr (soot.jimple.CastExpr)7 DefinitionStmt (soot.jimple.DefinitionStmt)7 NewArrayExpr (soot.jimple.NewArrayExpr)7