Search in sources :

Example 1 with LocalCreation

use of soot.jimple.toolkits.scalar.LocalCreation in project soot by Sable.

the class Util method addExceptionAfterUnit.

/**
 * Insert a runtime exception before unit u of body b. Useful to analyze
 * broken code (which make reference to inexisting class for instance)
 * exceptionType: e.g., "java.lang.RuntimeException"
 */
public static void addExceptionAfterUnit(Body b, String exceptionType, Unit u, String m) {
    LocalCreation lc = new LocalCreation(b.getLocals());
    Local l = lc.newLocal(RefType.v(exceptionType));
    List<Unit> newUnits = new ArrayList<Unit>();
    Unit u1 = Jimple.v().newAssignStmt(l, Jimple.v().newNewExpr(RefType.v(exceptionType)));
    Unit u2 = Jimple.v().newInvokeStmt(Jimple.v().newSpecialInvokeExpr(l, Scene.v().makeMethodRef(Scene.v().getSootClass(exceptionType), "<init>", Collections.singletonList((Type) RefType.v("java.lang.String")), VoidType.v(), false), StringConstant.v(m)));
    Unit u3 = Jimple.v().newThrowStmt(l);
    newUnits.add(u1);
    newUnits.add(u2);
    newUnits.add(u3);
    b.getUnits().insertBefore(newUnits, u);
}
Also used : RefType(soot.RefType) DoubleType(soot.DoubleType) FloatType(soot.FloatType) IntType(soot.IntType) ShortType(soot.ShortType) CharType(soot.CharType) LongType(soot.LongType) BooleanType(soot.BooleanType) ByteType(soot.ByteType) ArrayType(soot.ArrayType) Type(soot.Type) VoidType(soot.VoidType) LocalCreation(soot.jimple.toolkits.scalar.LocalCreation) ArrayList(java.util.ArrayList) Local(soot.Local) Unit(soot.Unit)

Example 2 with LocalCreation

use of soot.jimple.toolkits.scalar.LocalCreation 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 3 with LocalCreation

use of soot.jimple.toolkits.scalar.LocalCreation in project soot by Sable.

the class DexNullArrayRefTransformer method internalTransform.

protected void internalTransform(final Body body, String phaseName, Map<String, String> options) {
    final ExceptionalUnitGraph g = new ExceptionalUnitGraph(body, DalvikThrowAnalysis.v());
    final LocalDefs defs = LocalDefs.Factory.newLocalDefs(g);
    final LocalCreation lc = new LocalCreation(body.getLocals(), "ex");
    boolean changed = false;
    for (Iterator<Unit> unitIt = body.getUnits().snapshotIterator(); unitIt.hasNext(); ) {
        Stmt s = (Stmt) unitIt.next();
        if (s.containsArrayRef()) {
            // Check array reference
            Value base = s.getArrayRef().getBase();
            if (isAlwaysNullBefore(s, (Local) base, defs)) {
                createThrowStmt(body, s, lc);
                changed = true;
            }
        } else if (s instanceof AssignStmt) {
            AssignStmt ass = (AssignStmt) s;
            Value rightOp = ass.getRightOp();
            if (rightOp instanceof LengthExpr) {
                // Check lengthof expression
                LengthExpr l = (LengthExpr) ass.getRightOp();
                Value base = l.getOp();
                if (base instanceof IntConstant) {
                    IntConstant ic = (IntConstant) base;
                    if (ic.value == 0) {
                        createThrowStmt(body, s, lc);
                        changed = true;
                    }
                } else if (base == NullConstant.v() || isAlwaysNullBefore(s, (Local) base, defs)) {
                    createThrowStmt(body, s, lc);
                    changed = true;
                }
            }
        }
    }
    if (changed)
        UnreachableCodeEliminator.v().transform(body);
}
Also used : ExceptionalUnitGraph(soot.toolkits.graph.ExceptionalUnitGraph) LocalCreation(soot.jimple.toolkits.scalar.LocalCreation) AssignStmt(soot.jimple.AssignStmt) LengthExpr(soot.jimple.LengthExpr) Value(soot.Value) IntConstant(soot.jimple.IntConstant) Local(soot.Local) Unit(soot.Unit) LocalDefs(soot.toolkits.scalar.LocalDefs) Stmt(soot.jimple.Stmt) AssignStmt(soot.jimple.AssignStmt) DefinitionStmt(soot.jimple.DefinitionStmt)

Example 4 with LocalCreation

use of soot.jimple.toolkits.scalar.LocalCreation in project soot by Sable.

the class DexReturnValuePropagator method internalTransform.

@Override
protected void internalTransform(Body body, String phaseName, Map<String, String> options) {
    ExceptionalUnitGraph graph = new ExceptionalUnitGraph(body, DalvikThrowAnalysis.v(), true);
    LocalDefs localDefs = LocalDefs.Factory.newLocalDefs(graph);
    LocalUses localUses = null;
    LocalCreation localCreation = null;
    // a copy statement, we take the original operand
    for (Unit u : body.getUnits()) if (u instanceof ReturnStmt) {
        ReturnStmt retStmt = (ReturnStmt) u;
        if (retStmt.getOp() instanceof Local) {
            List<Unit> defs = localDefs.getDefsOfAt((Local) retStmt.getOp(), retStmt);
            if (defs.size() == 1 && defs.get(0) instanceof AssignStmt) {
                AssignStmt assign = (AssignStmt) defs.get(0);
                final Value rightOp = assign.getRightOp();
                final Value leftOp = assign.getLeftOp();
                // Copy over the left side if it is a local
                if (rightOp instanceof Local) {
                    // to return a;
                    if (!isRedefined((Local) rightOp, u, assign, graph))
                        retStmt.setOp(rightOp);
                } else if (rightOp instanceof Constant) {
                    retStmt.setOp(rightOp);
                } else // we rename the local to help splitting
                if (rightOp instanceof FieldRef) {
                    if (localUses == null)
                        localUses = LocalUses.Factory.newLocalUses(body, localDefs);
                    if (localUses.getUsesOf(assign).size() == 1) {
                        if (localCreation == null)
                            localCreation = new LocalCreation(body.getLocals(), "ret");
                        Local newLocal = localCreation.newLocal(leftOp.getType());
                        assign.setLeftOp(newLocal);
                        retStmt.setOp(newLocal);
                    }
                }
            }
        }
    }
}
Also used : ExceptionalUnitGraph(soot.toolkits.graph.ExceptionalUnitGraph) FieldRef(soot.jimple.FieldRef) LocalCreation(soot.jimple.toolkits.scalar.LocalCreation) AssignStmt(soot.jimple.AssignStmt) Constant(soot.jimple.Constant) Value(soot.Value) Local(soot.Local) ArrayList(java.util.ArrayList) List(java.util.List) LocalUses(soot.toolkits.scalar.LocalUses) Unit(soot.Unit) LocalDefs(soot.toolkits.scalar.LocalDefs) ReturnStmt(soot.jimple.ReturnStmt)

Aggregations

Local (soot.Local)4 Unit (soot.Unit)4 LocalCreation (soot.jimple.toolkits.scalar.LocalCreation)4 Value (soot.Value)3 AssignStmt (soot.jimple.AssignStmt)3 ArrayList (java.util.ArrayList)2 ExceptionalUnitGraph (soot.toolkits.graph.ExceptionalUnitGraph)2 LocalDefs (soot.toolkits.scalar.LocalDefs)2 HashMap (java.util.HashMap)1 List (java.util.List)1 ArrayType (soot.ArrayType)1 BooleanType (soot.BooleanType)1 ByteType (soot.ByteType)1 CharType (soot.CharType)1 DoubleType (soot.DoubleType)1 EquivalentValue (soot.EquivalentValue)1 FloatType (soot.FloatType)1 IntType (soot.IntType)1 LongType (soot.LongType)1 RefType (soot.RefType)1