Search in sources :

Example 36 with AssignStmt

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

the class SynchronizerManager method createClassFetcherFor.

/**
 * Creates a method which calls java.lang.Class.forName(String).
 *
 * The method should look like the following:
 *
 * <pre>
 *	         .static java.lang.Class class$(java.lang.String)
 *	         {
 *	             java.lang.String r0, $r5;
 *	             java.lang.ClassNotFoundException r1, $r3;
 *	             java.lang.Class $r2;
 *	             java.lang.NoClassDefFoundError $r4;
 *
 *	             r0 := @parameter0: java.lang.String;
 *
 *	         label0:
 *	             $r2 = .staticinvoke <java.lang.Class: java.lang.Class forName(java.lang.String)>(r0);
 *	             .return $r2;
 *
 *	         label1:
 *	             $r3 := @caughtexception;
 *	             r1 = $r3;
 *	             $r4 = .new java.lang.NoClassDefFoundError;
 *	             $r5 = .virtualinvoke r1.<java.lang.Throwable: java.lang.String getMessage()>();
 *	             .specialinvoke $r4.<java.lang.NoClassDefFoundError: .void <init>(java.lang.String)>($r5);
 *	             .throw $r4;
 *
 *	             .catch java.lang.ClassNotFoundException .from label0 .to label1 .with label1;
 *	         }
 * </pre>
 */
public SootMethod createClassFetcherFor(SootClass c, String methodName) {
    // Create the method
    SootMethod method = Scene.v().makeSootMethod(methodName, Arrays.asList(new Type[] { RefType.v("java.lang.String") }), RefType.v("java.lang.Class"), Modifier.STATIC);
    c.addMethod(method);
    // Create the method body
    {
        JimpleBody body = Jimple.v().newBody(method);
        method.setActiveBody(body);
        Chain units = body.getUnits();
        Local l_r0, l_r1, l_r2, l_r3, l_r4, l_r5;
        // Add some locals
        l_r0 = Jimple.v().newLocal("r0", RefType.v("java.lang.String"));
        l_r1 = Jimple.v().newLocal("r1", RefType.v("java.lang.ClassNotFoundException"));
        l_r2 = Jimple.v().newLocal("$r2", RefType.v("java.lang.Class"));
        l_r3 = Jimple.v().newLocal("$r3", RefType.v("java.lang.ClassNotFoundException"));
        l_r4 = Jimple.v().newLocal("$r4", RefType.v("java.lang.NoClassDefFoundError"));
        l_r5 = Jimple.v().newLocal("$r5", RefType.v("java.lang.String"));
        body.getLocals().add(l_r0);
        body.getLocals().add(l_r1);
        body.getLocals().add(l_r2);
        body.getLocals().add(l_r3);
        body.getLocals().add(l_r4);
        body.getLocals().add(l_r5);
        // add "r0 := @parameter0: java.lang.String"
        units.add(Jimple.v().newIdentityStmt(l_r0, Jimple.v().newParameterRef(RefType.v("java.lang.String"), 0)));
        // add "$r2 = .staticinvoke <java.lang.Class: java.lang.Class
        // forName(java.lang.String)>(r0);
        AssignStmt asi;
        units.add(asi = Jimple.v().newAssignStmt(l_r2, Jimple.v().newStaticInvokeExpr(Scene.v().getMethod("<java.lang.Class: java.lang.Class" + " forName(java.lang.String)>").makeRef(), Arrays.asList(new Value[] { l_r0 }))));
        // insert "return $r2;"
        units.add(Jimple.v().newReturnStmt(l_r2));
        // add "r3 := @caughtexception;"
        Stmt handlerStart;
        units.add(handlerStart = Jimple.v().newIdentityStmt(l_r3, Jimple.v().newCaughtExceptionRef()));
        // add "r1 = r3;"
        units.add(Jimple.v().newAssignStmt(l_r1, l_r3));
        // add "$r4 = .new java.lang.NoClassDefFoundError;"
        units.add(Jimple.v().newAssignStmt(l_r4, Jimple.v().newNewExpr(RefType.v("java.lang.NoClassDefFoundError"))));
        // add "$r5 = virtualinvoke r1.<java.lang.Throwable:
        // java.lang.String getMessage()>();"
        units.add(Jimple.v().newAssignStmt(l_r5, Jimple.v().newVirtualInvokeExpr(l_r1, Scene.v().getMethod("<java.lang.Throwable: java.lang.String getMessage()>").makeRef(), new LinkedList())));
        // add .specialinvoke $r4.<java.lang.NoClassDefFoundError: .void
        // <init>(java.lang.String)>($r5);
        units.add(Jimple.v().newInvokeStmt(Jimple.v().newSpecialInvokeExpr(l_r4, Scene.v().getMethod("<java.lang.NoClassDefFoundError: void" + " <init>(java.lang.String)>").makeRef(), Arrays.asList(new Value[] { l_r5 }))));
        // add .throw $r4;
        units.add(Jimple.v().newThrowStmt(l_r4));
        body.getTraps().add(Jimple.v().newTrap(Scene.v().getSootClass("java.lang.ClassNotFoundException"), asi, handlerStart, handlerStart));
    }
    return method;
}
Also used : Chain(soot.util.Chain) RefType(soot.RefType) Type(soot.Type) AssignStmt(soot.jimple.AssignStmt) Value(soot.Value) SootMethod(soot.SootMethod) Local(soot.Local) JimpleBody(soot.jimple.JimpleBody) LinkedList(java.util.LinkedList) IfStmt(soot.jimple.IfStmt) IdentityStmt(soot.jimple.IdentityStmt) ReturnStmt(soot.jimple.ReturnStmt) Stmt(soot.jimple.Stmt) AssignStmt(soot.jimple.AssignStmt)

Example 37 with AssignStmt

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

the class SynchronizerManager method getClassFetcherFor.

/**
 * Finds a method which calls java.lang.Class.forName(String). Searches for
 * names class$, _class$, __class$, etc. If no such method is found, creates
 * one and returns it.
 *
 * Uses dumb matching to do search. Not worth doing symbolic analysis for
 * this!
 */
public SootMethod getClassFetcherFor(SootClass c) {
    String methodName = "class$";
    for (; true; methodName = "_" + methodName) {
        SootMethod m = c.getMethodByNameUnsafe(methodName);
        if (m == null)
            return createClassFetcherFor(c, methodName);
        // Check signature.
        if (!m.getSignature().equals("<" + c.getName().replace('.', '$') + ": java.lang.Class " + methodName + "(java.lang.String)>"))
            continue;
        Body b = null;
        b = m.retrieveActiveBody();
        Iterator unitsIt = b.getUnits().iterator();
        if (!unitsIt.hasNext())
            continue;
        Stmt s = (Stmt) unitsIt.next();
        if (!(s instanceof IdentityStmt))
            continue;
        IdentityStmt is = (IdentityStmt) s;
        Value lo = is.getLeftOp(), ro = is.getRightOp();
        if (!(ro instanceof ParameterRef))
            continue;
        ParameterRef pr = (ParameterRef) ro;
        if (pr.getIndex() != 0)
            continue;
        if (!unitsIt.hasNext())
            continue;
        s = (Stmt) unitsIt.next();
        if (!(s instanceof AssignStmt))
            continue;
        AssignStmt as = (AssignStmt) s;
        Value retVal = as.getLeftOp(), ie = as.getRightOp();
        if (!ie.toString().equals(".staticinvoke <java.lang.Class: java.lang.Class forName(java.lang.String)>(" + lo + ")"))
            continue;
        if (!unitsIt.hasNext())
            continue;
        s = (Stmt) unitsIt.next();
        if (!(s instanceof ReturnStmt))
            continue;
        ReturnStmt rs = (ReturnStmt) s;
        if (!rs.getOp().equivTo(retVal))
            continue;
        /* in particular, it certainly returns Class.forName(arg). */
        return m;
    }
}
Also used : ParameterRef(soot.jimple.ParameterRef) AssignStmt(soot.jimple.AssignStmt) Iterator(java.util.Iterator) Value(soot.Value) SootMethod(soot.SootMethod) Body(soot.Body) JimpleBody(soot.jimple.JimpleBody) ReturnStmt(soot.jimple.ReturnStmt) IdentityStmt(soot.jimple.IdentityStmt) IfStmt(soot.jimple.IfStmt) IdentityStmt(soot.jimple.IdentityStmt) ReturnStmt(soot.jimple.ReturnStmt) Stmt(soot.jimple.Stmt) AssignStmt(soot.jimple.AssignStmt)

Example 38 with AssignStmt

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

the class BusyCodeMotion method internalTransform.

/**
 * performs the busy code motion.
 */
protected void internalTransform(Body b, String phaseName, Map<String, String> opts) {
    BCMOptions options = new BCMOptions(opts);
    HashMap<EquivalentValue, Local> expToHelper = new HashMap<EquivalentValue, Local>();
    Chain<Unit> unitChain = b.getUnits();
    if (Options.v().verbose())
        logger.debug("[" + b.getMethod().getName() + "]     performing Busy Code Motion...");
    CriticalEdgeRemover.v().transform(b, phaseName + ".cer");
    UnitGraph graph = new BriefUnitGraph(b);
    /* map each unit to its RHS. only take binary expressions */
    Map<Unit, EquivalentValue> unitToEquivRhs = new UnitMap<EquivalentValue>(b, graph.size() + 1, 0.7f) {

        protected EquivalentValue mapTo(Unit unit) {
            Value tmp = SootFilter.noInvokeRhs(unit);
            Value tmp2 = SootFilter.binop(tmp);
            if (tmp2 == null)
                tmp2 = SootFilter.concreteRef(tmp);
            return SootFilter.equiVal(tmp2);
        }
    };
    /* same as before, but without exception-throwing expressions */
    Map<Unit, EquivalentValue> unitToNoExceptionEquivRhs = new UnitMap<EquivalentValue>(b, graph.size() + 1, 0.7f) {

        protected EquivalentValue mapTo(Unit unit) {
            Value tmp = SootFilter.binopRhs(unit);
            tmp = SootFilter.noExceptionThrowing(tmp);
            return SootFilter.equiVal(tmp);
        }
    };
    /* if a more precise sideeffect-tester comes out, please change it here! */
    SideEffectTester sideEffect;
    if (Scene.v().hasCallGraph() && !options.naive_side_effect()) {
        sideEffect = new PASideEffectTester();
    } else {
        sideEffect = new NaiveSideEffectTester();
    }
    sideEffect.newMethod(b.getMethod());
    UpSafetyAnalysis upSafe = new UpSafetyAnalysis(graph, unitToEquivRhs, sideEffect);
    DownSafetyAnalysis downSafe = new DownSafetyAnalysis(graph, unitToNoExceptionEquivRhs, sideEffect);
    EarliestnessComputation earliest = new EarliestnessComputation(graph, upSafe, downSafe, sideEffect);
    LocalCreation localCreation = new LocalCreation(b.getLocals(), PREFIX);
    Iterator<Unit> unitIt = unitChain.snapshotIterator();
    {
        /* insert the computations at the earliest positions */
        while (unitIt.hasNext()) {
            Unit currentUnit = unitIt.next();
            for (EquivalentValue equiVal : earliest.getFlowBefore(currentUnit)) {
                // Value exp = equiVal.getValue();
                /* get the unic helper-name for this expression */
                Local helper = expToHelper.get(equiVal);
                // the beginning of the method
                if (currentUnit instanceof IdentityStmt)
                    currentUnit = getFirstNonIdentityStmt(b);
                if (helper == null) {
                    helper = localCreation.newLocal(equiVal.getType());
                    expToHelper.put(equiVal, helper);
                }
                /* insert a new Assignment-stmt before the currentUnit */
                Value insertValue = Jimple.cloneIfNecessary(equiVal.getValue());
                Unit firstComp = Jimple.v().newAssignStmt(helper, insertValue);
                unitChain.insertBefore(firstComp, currentUnit);
            }
        }
    }
    {
        /* replace old computations by the helper-vars */
        unitIt = unitChain.iterator();
        while (unitIt.hasNext()) {
            Unit currentUnit = unitIt.next();
            EquivalentValue rhs = unitToEquivRhs.get(currentUnit);
            if (rhs != null) {
                Local helper = expToHelper.get(rhs);
                if (helper != null)
                    ((AssignStmt) currentUnit).setRightOp(helper);
            }
        }
    }
    if (Options.v().verbose())
        logger.debug("[" + b.getMethod().getName() + "]     Busy Code Motion done!");
}
Also used : EquivalentValue(soot.EquivalentValue) PASideEffectTester(soot.jimple.toolkits.pointer.PASideEffectTester) SideEffectTester(soot.SideEffectTester) NaiveSideEffectTester(soot.jimple.NaiveSideEffectTester) BCMOptions(soot.options.BCMOptions) HashMap(java.util.HashMap) PASideEffectTester(soot.jimple.toolkits.pointer.PASideEffectTester) LocalCreation(soot.jimple.toolkits.scalar.LocalCreation) AssignStmt(soot.jimple.AssignStmt) Local(soot.Local) BriefUnitGraph(soot.toolkits.graph.BriefUnitGraph) Unit(soot.Unit) UnitGraph(soot.toolkits.graph.UnitGraph) BriefUnitGraph(soot.toolkits.graph.BriefUnitGraph) EquivalentValue(soot.EquivalentValue) Value(soot.Value) NaiveSideEffectTester(soot.jimple.NaiveSideEffectTester) UnitMap(soot.util.UnitMap) IdentityStmt(soot.jimple.IdentityStmt)

Example 39 with AssignStmt

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

the class IdentityCastEliminator method internalTransform.

@Override
protected void internalTransform(Body b, String phaseName, Map<String, String> options) {
    for (Iterator<Unit> unitIt = b.getUnits().iterator(); unitIt.hasNext(); ) {
        Unit curUnit = unitIt.next();
        if (curUnit instanceof AssignStmt) {
            AssignStmt assignStmt = (AssignStmt) curUnit;
            if (assignStmt.getLeftOp() instanceof Local && assignStmt.getRightOp() instanceof CastExpr) {
                CastExpr ce = (CastExpr) assignStmt.getRightOp();
                Type orgType = ce.getOp().getType();
                Type newType = ce.getCastType();
                // with a normal assignment.
                if (orgType == newType) {
                    if (assignStmt.getLeftOp() == ce.getOp())
                        unitIt.remove();
                    else
                        assignStmt.setRightOp(ce.getOp());
                }
            }
        }
    }
}
Also used : Type(soot.Type) AssignStmt(soot.jimple.AssignStmt) CastExpr(soot.jimple.CastExpr) Local(soot.Local) Unit(soot.Unit)

Example 40 with AssignStmt

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

the class AccessManager method createAccessorMethod.

/**
 * Turns a field access or method call into a call to an accessor method.
 * Reuses existing accessors based on name mangling (see createAccessorName)
 *
 * @param container
 * @param stmt
 */
public static void createAccessorMethod(SootMethod container, Stmt stmt) {
    // System.out.println("Creating accessor method: \n" +
    // " method: " + container + " \n" +
    // " stmt: " + stmt);
    Body containerBody = container.getActiveBody();
    soot.util.Chain containerStmts = containerBody.getUnits();
    if (!containerStmts.contains(stmt))
        throw new RuntimeException();
    if (stmt.containsInvokeExpr()) {
        createInvokeAccessor(container, stmt);
    } else if (stmt instanceof AssignStmt) {
        AssignStmt as = (AssignStmt) stmt;
        FieldRef ref;
        if (as.getLeftOp() instanceof FieldRef) {
            // set
            ref = (FieldRef) as.getLeftOp();
            createSetAccessor(container, as, ref);
        } else if (as.getRightOp() instanceof FieldRef) {
            // get
            ref = (FieldRef) as.getRightOp();
            createGetAccessor(container, as, ref);
        } else {
            throw new RuntimeException("Expected class member access");
        }
    } else
        throw new RuntimeException("Expected class member access");
}
Also used : FieldRef(soot.jimple.FieldRef) InstanceFieldRef(soot.jimple.InstanceFieldRef) AssignStmt(soot.jimple.AssignStmt) Body(soot.Body)

Aggregations

AssignStmt (soot.jimple.AssignStmt)83 Local (soot.Local)50 Value (soot.Value)44 Unit (soot.Unit)40 Type (soot.Type)28 Stmt (soot.jimple.Stmt)24 InvokeExpr (soot.jimple.InvokeExpr)20 RefType (soot.RefType)19 ArrayRef (soot.jimple.ArrayRef)19 ArrayType (soot.ArrayType)17 CastExpr (soot.jimple.CastExpr)17 InvokeStmt (soot.jimple.InvokeStmt)17 ArrayList (java.util.ArrayList)15 IdentityStmt (soot.jimple.IdentityStmt)15 DefinitionStmt (soot.jimple.DefinitionStmt)13 FieldRef (soot.jimple.FieldRef)13 InstanceFieldRef (soot.jimple.InstanceFieldRef)13 IntConstant (soot.jimple.IntConstant)13 ReturnStmt (soot.jimple.ReturnStmt)13 HashSet (java.util.HashSet)12