Search in sources :

Example 91 with Unit

use of soot.Unit in project soot by Sable.

the class SynchronizerManager method synchronizeStmtOn.

/**
 * Wraps stmt around a monitor associated with local lock. When inlining or
 * static method binding, this is the former base of the invoke expression.
 */
public void synchronizeStmtOn(Stmt stmt, JimpleBody b, Local lock) {
    Chain units = b.getUnits();
    // TrapManager.splitTrapsAgainst(b, stmt, (Stmt)units.getSuccOf(stmt));
    units.insertBefore(Jimple.v().newEnterMonitorStmt(lock), stmt);
    Stmt exitMon = Jimple.v().newExitMonitorStmt(lock);
    units.insertAfter(exitMon, stmt);
    // Ok. That was the easy part.
    // We also need to modify exception blocks to exit the monitor
    // (they have conveniently been pre-split)
    // Actually, we don't need to do this.
    // {
    // List traps = TrapManager.getTrapsAt(stmt, b);
    // Iterator trapsIt = traps.iterator();
    // while (trapsIt.hasNext())
    // {
    // Trap t = (Trap)trapsIt.next();
    // Stmt s = (Stmt)units.getLast();
    // Stmt newCaughtRef = (Stmt)t.getHandlerUnit().clone();
    // List l = new ArrayList();
    // l.add(newCaughtRef);
    // l.add(exitMon.clone());
    // l.add(Jimple.v().newGotoStmt((Stmt)units.getSuccOf((Stmt)t.getHandlerUnit())));
    // units.insertAfter(l, s);
    // t.setHandlerUnit(newCaughtRef);
    // }
    // }
    // and also we must add a catch Throwable exception block in the
    // appropriate place.
    {
        Stmt newGoto = Jimple.v().newGotoStmt((Stmt) units.getSuccOf(exitMon));
        units.insertAfter(newGoto, exitMon);
        List<Unit> l = new ArrayList<Unit>();
        Local eRef = Jimple.v().newLocal("__exception", RefType.v("java.lang.Throwable"));
        b.getLocals().add(eRef);
        Stmt handlerStmt = Jimple.v().newIdentityStmt(eRef, Jimple.v().newCaughtExceptionRef());
        l.add(handlerStmt);
        l.add((Stmt) exitMon.clone());
        l.add(Jimple.v().newThrowStmt(eRef));
        units.insertAfter(l, newGoto);
        Trap newTrap = Jimple.v().newTrap(Scene.v().getSootClass("java.lang.Throwable"), stmt, (Stmt) units.getSuccOf(stmt), handlerStmt);
        b.getTraps().addFirst(newTrap);
    }
}
Also used : Chain(soot.util.Chain) Local(soot.Local) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) List(java.util.List) Trap(soot.Trap) Unit(soot.Unit) IfStmt(soot.jimple.IfStmt) IdentityStmt(soot.jimple.IdentityStmt) ReturnStmt(soot.jimple.ReturnStmt) Stmt(soot.jimple.Stmt) AssignStmt(soot.jimple.AssignStmt)

Example 92 with Unit

use of soot.Unit in project soot by Sable.

the class DexArrayInitDetector method constructArrayInitializations.

/**
 * Constructs packed array initializations from the individual element
 * assignments in the given body
 * @param body The body in which to look for element assignments
 */
public void constructArrayInitializations(Body body) {
    // Find an array construction followed by consecutive element
    // assignments
    Unit arrayInitStmt = null;
    List<Value> arrayValues = null;
    Set<Unit> curIgnoreUnits = null;
    int arraySize = 0;
    for (Unit u : body.getUnits()) {
        if (!(u instanceof AssignStmt)) {
            arrayValues = null;
            continue;
        }
        AssignStmt assignStmt = (AssignStmt) u;
        if (assignStmt.getRightOp() instanceof NewArrayExpr) {
            NewArrayExpr newArrayExp = (NewArrayExpr) assignStmt.getRightOp();
            if (newArrayExp.getSize() instanceof IntConstant) {
                IntConstant intConst = (IntConstant) newArrayExp.getSize();
                arrayValues = new ArrayList<Value>();
                arraySize = intConst.value;
                curIgnoreUnits = new HashSet<Unit>();
            } else {
                arrayValues = null;
            }
        } else if (assignStmt.getLeftOp() instanceof ArrayRef && assignStmt.getRightOp() instanceof IntConstant && /*NumericConstant*/
        arrayValues != null) {
            ArrayRef aref = (ArrayRef) assignStmt.getLeftOp();
            if (aref.getIndex() instanceof IntConstant) {
                IntConstant intConst = (IntConstant) aref.getIndex();
                if (intConst.value == arrayValues.size()) {
                    arrayValues.add(assignStmt.getRightOp());
                    if (intConst.value == 0)
                        arrayInitStmt = u;
                    else if (intConst.value == arraySize - 1) {
                        curIgnoreUnits.add(u);
                        checkAndSave(arrayInitStmt, arrayValues, arraySize, curIgnoreUnits);
                        arrayValues = null;
                    } else
                        curIgnoreUnits.add(u);
                } else {
                    arrayValues = null;
                }
            } else {
                arrayValues = null;
            }
        } else {
            arrayValues = null;
        }
    }
}
Also used : ArrayRef(soot.jimple.ArrayRef) NewArrayExpr(soot.jimple.NewArrayExpr) AssignStmt(soot.jimple.AssignStmt) Value(soot.Value) IntConstant(soot.jimple.IntConstant) Unit(soot.Unit)

Example 93 with Unit

use of soot.Unit in project soot by Sable.

the class StmtVisitor method caseTableSwitchStmt.

@Override
public void caseTableSwitchStmt(TableSwitchStmt stmt) {
    exprV.setOrigStmt(stmt);
    constantV.setOrigStmt(stmt);
    // create payload that references the switch's targets
    int firstKey = stmt.getLowIndex();
    List<Unit> targets = stmt.getTargets();
    PackedSwitchPayload payload = new PackedSwitchPayload(firstKey, targets);
    payloads.add(payload);
    // create packed-switch instruction that references the payload
    Value key = stmt.getKey();
    Stmt defaultTarget = (Stmt) stmt.getDefaultTarget();
    addInsn(buildSwitchInsn(Opcode.PACKED_SWITCH, key, defaultTarget, payload, stmt), stmt);
}
Also used : PackedSwitchPayload(soot.toDex.instructions.PackedSwitchPayload) Value(soot.Value) Unit(soot.Unit) BreakpointStmt(soot.jimple.BreakpointStmt) ReturnVoidStmt(soot.jimple.ReturnVoidStmt) InvokeStmt(soot.jimple.InvokeStmt) EnterMonitorStmt(soot.jimple.EnterMonitorStmt) NopStmt(soot.jimple.NopStmt) GotoStmt(soot.jimple.GotoStmt) RetStmt(soot.jimple.RetStmt) AssignStmt(soot.jimple.AssignStmt) ThrowStmt(soot.jimple.ThrowStmt) IfStmt(soot.jimple.IfStmt) IdentityStmt(soot.jimple.IdentityStmt) TableSwitchStmt(soot.jimple.TableSwitchStmt) MonitorStmt(soot.jimple.MonitorStmt) LookupSwitchStmt(soot.jimple.LookupSwitchStmt) ReturnStmt(soot.jimple.ReturnStmt) ExitMonitorStmt(soot.jimple.ExitMonitorStmt) Stmt(soot.jimple.Stmt)

Example 94 with Unit

use of soot.Unit in project soot by Sable.

the class TrapTransformer method getUnitsWithMonitor.

public Set<Unit> getUnitsWithMonitor(UnitGraph ug) {
    // Idea: Associate each unit with a set of monitors held at that
    // statement
    MultiMap<Unit, Value> unitMonitors = new HashMultiMap<>();
    // Start at the heads of the unit graph
    List<Unit> workList = new ArrayList<>();
    Set<Unit> doneSet = new HashSet<>();
    for (Unit head : ug.getHeads()) {
        workList.add(head);
    }
    while (!workList.isEmpty()) {
        Unit curUnit = workList.remove(0);
        boolean hasChanged = false;
        Value exitValue = null;
        if (curUnit instanceof EnterMonitorStmt) {
            // We enter a new monitor
            EnterMonitorStmt ems = (EnterMonitorStmt) curUnit;
            hasChanged = unitMonitors.put(curUnit, ems.getOp());
        } else if (curUnit instanceof ExitMonitorStmt) {
            // We leave a monitor
            ExitMonitorStmt ems = (ExitMonitorStmt) curUnit;
            exitValue = ems.getOp();
        }
        // Copy over the monitors from the predecessors
        for (Unit pred : ug.getPredsOf(curUnit)) for (Value v : unitMonitors.get(pred)) if (v != exitValue)
            if (unitMonitors.put(curUnit, v))
                hasChanged = true;
        // Work on the successors
        if (doneSet.add(curUnit) || hasChanged)
            workList.addAll(ug.getSuccsOf(curUnit));
    }
    return unitMonitors.keySet();
}
Also used : ExitMonitorStmt(soot.jimple.ExitMonitorStmt) Value(soot.Value) ArrayList(java.util.ArrayList) HashMultiMap(soot.util.HashMultiMap) Unit(soot.Unit) EnterMonitorStmt(soot.jimple.EnterMonitorStmt) HashSet(java.util.HashSet)

Example 95 with Unit

use of soot.Unit in project soot by Sable.

the class TrapTightener method internalTransform.

protected void internalTransform(Body body, String phaseName, Map<String, String> options) {
    if (this.throwAnalysis == null)
        this.throwAnalysis = Scene.v().getDefaultThrowAnalysis();
    if (Options.v().verbose())
        logger.debug("[" + body.getMethod().getName() + "] Tightening trap boundaries...");
    Chain<Trap> trapChain = body.getTraps();
    Chain<Unit> unitChain = body.getUnits();
    if (trapChain.size() > 0) {
        ExceptionalUnitGraph graph = new ExceptionalUnitGraph(body, throwAnalysis);
        Set<Unit> unitsWithMonitor = getUnitsWithMonitor(graph);
        for (Iterator<Trap> trapIt = trapChain.iterator(); trapIt.hasNext(); ) {
            Trap trap = trapIt.next();
            boolean isCatchAll = trap.getException().getName().equals("java.lang.Throwable");
            Unit firstTrappedUnit = trap.getBeginUnit();
            Unit firstTrappedThrower = null;
            Unit firstUntrappedUnit = trap.getEndUnit();
            Unit lastTrappedUnit = unitChain.getPredOf(firstUntrappedUnit);
            Unit lastTrappedThrower = null;
            for (Unit u = firstTrappedUnit; u != null && u != firstUntrappedUnit; u = unitChain.getSuccOf(u)) {
                if (mightThrowTo(graph, u, trap)) {
                    firstTrappedThrower = u;
                    break;
                }
                // active monitor, we need to keep the block
                if (isCatchAll && unitsWithMonitor.contains(u)) {
                    if (firstTrappedThrower == null)
                        firstTrappedThrower = u;
                    break;
                }
            }
            if (firstTrappedThrower != null) {
                for (Unit u = lastTrappedUnit; u != null; u = unitChain.getPredOf(u)) {
                    if (mightThrowTo(graph, u, trap)) {
                        lastTrappedThrower = u;
                        break;
                    }
                    // has an, active monitor, we need to keep the block
                    if (isCatchAll && unitsWithMonitor.contains(u)) {
                        lastTrappedThrower = u;
                        break;
                    }
                }
            }
            // remove the complete trap.
            if (firstTrappedThrower == null)
                trapIt.remove();
            else {
                if (firstTrappedThrower != null && firstTrappedUnit != firstTrappedThrower) {
                    trap.setBeginUnit(firstTrappedThrower);
                }
                if (lastTrappedThrower == null) {
                    lastTrappedThrower = firstTrappedUnit;
                }
                if (lastTrappedUnit != lastTrappedThrower) {
                    trap.setEndUnit(unitChain.getSuccOf(lastTrappedThrower));
                }
            }
        }
    }
}
Also used : ExceptionalUnitGraph(soot.toolkits.graph.ExceptionalUnitGraph) Trap(soot.Trap) Unit(soot.Unit)

Aggregations

Unit (soot.Unit)240 Local (soot.Local)77 Stmt (soot.jimple.Stmt)77 Value (soot.Value)74 ArrayList (java.util.ArrayList)65 AssignStmt (soot.jimple.AssignStmt)58 SootMethod (soot.SootMethod)47 Body (soot.Body)37 InvokeStmt (soot.jimple.InvokeStmt)35 Type (soot.Type)34 HashSet (java.util.HashSet)33 ValueBox (soot.ValueBox)33 InvokeExpr (soot.jimple.InvokeExpr)33 Trap (soot.Trap)32 RefType (soot.RefType)30 IdentityStmt (soot.jimple.IdentityStmt)28 HashMap (java.util.HashMap)27 IfStmt (soot.jimple.IfStmt)27 DefinitionStmt (soot.jimple.DefinitionStmt)25 List (java.util.List)23