Search in sources :

Example 1 with Ref

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

the class ClassRenamer method internalTransform.

@Override
protected void internalTransform(String phaseName, Map<String, String> options) {
    if (isVerbose()) {
        logger.debug("Transforming Class Names...");
    }
    BodyBuilder.retrieveAllBodies();
    BodyBuilder.retrieveAllNames();
    final SootClass mainClass = getMainClassSafely();
    // iterate through application classes, rename classes with junk
    for (SootClass sootClass : Scene.v().getApplicationClasses()) {
        final String className = sootClass.getName();
        if (sootClass.equals(mainClass) || oldToNewClassNames.containsValue(className) || soot.jbco.Main.getWeight(phaseName, className) == 0) {
            continue;
        }
        String newClassName = oldToNewClassNames.get(className);
        if (newClassName == null) {
            newClassName = getNewName(getPackageName(className), className);
        }
        sootClass.setName(newClassName);
        RefType crt = RefType.v(newClassName);
        crt.setSootClass(sootClass);
        sootClass.setRefType(crt);
        sootClass.setResolvingLevel(SootClass.BODIES);
        // will this fix dangling classes?
        // scene.addRefType(sootClass.getType());
        newNameToClass.put(newClassName, sootClass);
        if (isVerbose()) {
            logger.info("\tRenaming " + className + " to " + newClassName);
        }
    }
    Scene.v().releaseActiveHierarchy();
    Scene.v().setFastHierarchy(new FastHierarchy());
    if (isVerbose()) {
        logger.info("\r\tUpdating bytecode class references");
    }
    for (SootClass sootClass : Scene.v().getApplicationClasses()) {
        for (SootMethod sootMethod : sootClass.getMethods()) {
            if (!sootMethod.isConcrete()) {
                continue;
            }
            if (isVerbose()) {
                logger.info("\t\t" + sootMethod.getSignature());
            }
            Body aBody;
            try {
                aBody = sootMethod.getActiveBody();
            } catch (Exception e) {
                continue;
            }
            for (Unit u : aBody.getUnits()) {
                for (ValueBox vb : u.getUseAndDefBoxes()) {
                    Value v = vb.getValue();
                    if (v instanceof ClassConstant) {
                        ClassConstant constant = (ClassConstant) v;
                        RefType type = (RefType) constant.toSootType();
                        RefType updatedType = type.getSootClass().getType();
                        vb.setValue(ClassConstant.fromType(updatedType));
                    } else if (v instanceof Expr) {
                        if (v instanceof CastExpr) {
                            CastExpr castExpr = (CastExpr) v;
                            updateType(castExpr.getCastType());
                        } else if (v instanceof InstanceOfExpr) {
                            InstanceOfExpr instanceOfExpr = (InstanceOfExpr) v;
                            updateType(instanceOfExpr.getCheckType());
                        }
                    } else if (v instanceof Ref) {
                        updateType(v.getType());
                    }
                }
            }
        }
    }
    Scene.v().releaseActiveHierarchy();
    Scene.v().setFastHierarchy(new FastHierarchy());
}
Also used : SootClass(soot.SootClass) Unit(soot.Unit) InstanceOfExpr(soot.jimple.InstanceOfExpr) RefType(soot.RefType) FastHierarchy(soot.FastHierarchy) Ref(soot.jimple.Ref) Expr(soot.jimple.Expr) InstanceOfExpr(soot.jimple.InstanceOfExpr) CastExpr(soot.jimple.CastExpr) ValueBox(soot.ValueBox) Value(soot.Value) CastExpr(soot.jimple.CastExpr) SootMethod(soot.SootMethod) Body(soot.Body) ClassConstant(soot.jimple.ClassConstant)

Example 2 with Ref

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

the class IFDSPossibleTypes method createFlowFunctionsFactory.

public FlowFunctions<Unit, Pair<Value, Type>, SootMethod> createFlowFunctionsFactory() {
    return new FlowFunctions<Unit, Pair<Value, Type>, SootMethod>() {

        public FlowFunction<Pair<Value, Type>> getNormalFlowFunction(Unit src, Unit dest) {
            if (src instanceof DefinitionStmt) {
                DefinitionStmt defnStmt = (DefinitionStmt) src;
                if (defnStmt.containsInvokeExpr())
                    return Identity.v();
                final Value right = defnStmt.getRightOp();
                final Value left = defnStmt.getLeftOp();
                // won't track primitive-typed variables
                if (right.getType() instanceof PrimType)
                    return Identity.v();
                if (right instanceof Constant || right instanceof NewExpr) {
                    return new FlowFunction<Pair<Value, Type>>() {

                        public Set<Pair<Value, Type>> computeTargets(Pair<Value, Type> source) {
                            if (source == zeroValue()) {
                                Set<Pair<Value, Type>> res = new LinkedHashSet<Pair<Value, Type>>();
                                res.add(new Pair<Value, Type>(left, right.getType()));
                                res.add(zeroValue());
                                return res;
                            } else if (source.getO1() instanceof Local && source.getO1().equivTo(left)) {
                                // strong update for local variables
                                return Collections.emptySet();
                            } else {
                                return Collections.singleton(source);
                            }
                        }
                    };
                } else if (right instanceof Ref || right instanceof Local) {
                    return new FlowFunction<Pair<Value, Type>>() {

                        public Set<Pair<Value, Type>> computeTargets(final Pair<Value, Type> source) {
                            Value value = source.getO1();
                            if (source.getO1() instanceof Local && source.getO1().equivTo(left)) {
                                // strong update for local variables
                                return Collections.emptySet();
                            } else if (maybeSameLocation(value, right)) {
                                return new LinkedHashSet<Pair<Value, Type>>() {

                                    {
                                        add(new Pair<Value, Type>(left, source.getO2()));
                                        add(source);
                                    }
                                };
                            } else {
                                return Collections.singleton(source);
                            }
                        }

                        private boolean maybeSameLocation(Value v1, Value v2) {
                            if (!(v1 instanceof InstanceFieldRef && v2 instanceof InstanceFieldRef) && !(v1 instanceof ArrayRef && v2 instanceof ArrayRef)) {
                                return v1.equivTo(v2);
                            }
                            if (v1 instanceof InstanceFieldRef && v2 instanceof InstanceFieldRef) {
                                InstanceFieldRef ifr1 = (InstanceFieldRef) v1;
                                InstanceFieldRef ifr2 = (InstanceFieldRef) v2;
                                if (!ifr1.getField().getName().equals(ifr2.getField().getName()))
                                    return false;
                                Local base1 = (Local) ifr1.getBase();
                                Local base2 = (Local) ifr2.getBase();
                                PointsToAnalysis pta = Scene.v().getPointsToAnalysis();
                                PointsToSet pts1 = pta.reachingObjects(base1);
                                PointsToSet pts2 = pta.reachingObjects(base2);
                                return pts1.hasNonEmptyIntersection(pts2);
                            } else {
                                // v1 instanceof ArrayRef && v2 instanceof ArrayRef
                                ArrayRef ar1 = (ArrayRef) v1;
                                ArrayRef ar2 = (ArrayRef) v2;
                                Local base1 = (Local) ar1.getBase();
                                Local base2 = (Local) ar2.getBase();
                                PointsToAnalysis pta = Scene.v().getPointsToAnalysis();
                                PointsToSet pts1 = pta.reachingObjects(base1);
                                PointsToSet pts2 = pta.reachingObjects(base2);
                                return pts1.hasNonEmptyIntersection(pts2);
                            }
                        }
                    };
                }
            }
            return Identity.v();
        }

        public FlowFunction<Pair<Value, Type>> getCallFlowFunction(final Unit src, final SootMethod dest) {
            Stmt stmt = (Stmt) src;
            InvokeExpr ie = stmt.getInvokeExpr();
            final List<Value> callArgs = ie.getArgs();
            final List<Local> paramLocals = new ArrayList<Local>();
            for (int i = 0; i < dest.getParameterCount(); i++) {
                paramLocals.add(dest.getActiveBody().getParameterLocal(i));
            }
            return new FlowFunction<Pair<Value, Type>>() {

                public Set<Pair<Value, Type>> computeTargets(Pair<Value, Type> source) {
                    if (!dest.getName().equals("<clinit>") && !dest.getSubSignature().equals("void run()")) {
                        Value value = source.getO1();
                        int argIndex = callArgs.indexOf(value);
                        if (argIndex > -1) {
                            return Collections.singleton(new Pair<Value, Type>(paramLocals.get(argIndex), source.getO2()));
                        }
                    }
                    return Collections.emptySet();
                }
            };
        }

        public FlowFunction<Pair<Value, Type>> getReturnFlowFunction(Unit callSite, SootMethod callee, Unit exitStmt, Unit retSite) {
            if (exitStmt instanceof ReturnStmt) {
                ReturnStmt returnStmt = (ReturnStmt) exitStmt;
                Value op = returnStmt.getOp();
                if (op instanceof Local) {
                    if (callSite instanceof DefinitionStmt) {
                        DefinitionStmt defnStmt = (DefinitionStmt) callSite;
                        Value leftOp = defnStmt.getLeftOp();
                        if (leftOp instanceof Local) {
                            final Local tgtLocal = (Local) leftOp;
                            final Local retLocal = (Local) op;
                            return new FlowFunction<Pair<Value, Type>>() {

                                public Set<Pair<Value, Type>> computeTargets(Pair<Value, Type> source) {
                                    if (source == retLocal)
                                        return Collections.singleton(new Pair<Value, Type>(tgtLocal, source.getO2()));
                                    return Collections.emptySet();
                                }
                            };
                        }
                    }
                }
            }
            return KillAll.v();
        }

        public FlowFunction<Pair<Value, Type>> getCallToReturnFlowFunction(Unit call, Unit returnSite) {
            return Identity.v();
        }
    };
}
Also used : LinkedHashSet(java.util.LinkedHashSet) PointsToSet(soot.PointsToSet) LinkedHashSet(java.util.LinkedHashSet) Set(java.util.Set) Constant(soot.jimple.Constant) ArrayList(java.util.ArrayList) Unit(soot.Unit) FlowFunctions(heros.FlowFunctions) ReturnStmt(soot.jimple.ReturnStmt) Stmt(soot.jimple.Stmt) DefinitionStmt(soot.jimple.DefinitionStmt) ArrayRef(soot.jimple.ArrayRef) InvokeExpr(soot.jimple.InvokeExpr) InstanceFieldRef(soot.jimple.InstanceFieldRef) PrimType(soot.PrimType) PointsToAnalysis(soot.PointsToAnalysis) Pair(soot.toolkits.scalar.Pair) PointsToSet(soot.PointsToSet) FlowFunction(heros.FlowFunction) Local(soot.Local) UnknownType(soot.UnknownType) Type(soot.Type) PrimType(soot.PrimType) ArrayRef(soot.jimple.ArrayRef) Ref(soot.jimple.Ref) InstanceFieldRef(soot.jimple.InstanceFieldRef) Value(soot.Value) NewExpr(soot.jimple.NewExpr) SootMethod(soot.SootMethod) DefinitionStmt(soot.jimple.DefinitionStmt) ReturnStmt(soot.jimple.ReturnStmt)

Example 3 with Ref

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

the class LockAllocationBodyTransformer method internalTransform.

protected void internalTransform(Body b, FlowSet fs, List<CriticalSectionGroup> groups, boolean[] insertedGlobalLock) {
    // 
    JimpleBody j = (JimpleBody) b;
    SootMethod thisMethod = b.getMethod();
    PatchingChain<Unit> units = b.getUnits();
    Iterator<Unit> unitIt = units.iterator();
    Unit firstUnit = j.getFirstNonIdentityStmt();
    Unit lastUnit = units.getLast();
    // Objects of synchronization, plus book keeping
    Local[] lockObj = new Local[groups.size()];
    boolean[] addedLocalLockObj = new boolean[groups.size()];
    SootField[] globalLockObj = new SootField[groups.size()];
    for (int i = 1; i < groups.size(); i++) {
        lockObj[i] = Jimple.v().newLocal("lockObj" + i, RefType.v("java.lang.Object"));
        addedLocalLockObj[i] = false;
        globalLockObj[i] = null;
    }
    // Get references to them if they do already exist.
    for (int i = 1; i < groups.size(); i++) {
        CriticalSectionGroup tnGroup = groups.get(i);
        if (!tnGroup.useDynamicLock && !tnGroup.useLocksets) {
            if (!insertedGlobalLock[i]) {
                // use it!
                try {
                    globalLockObj[i] = Scene.v().getMainClass().getFieldByName("globalLockObj" + i);
                // field already exists
                } catch (RuntimeException re) {
                    // field does not yet exist (or, as a pre-existing
                    // error, there is more than one field by this name)
                    globalLockObj[i] = Scene.v().makeSootField("globalLockObj" + i, RefType.v("java.lang.Object"), Modifier.STATIC | Modifier.PUBLIC);
                    Scene.v().getMainClass().addField(globalLockObj[i]);
                }
                insertedGlobalLock[i] = true;
            } else {
                globalLockObj[i] = Scene.v().getMainClass().getFieldByName("globalLockObj" + i);
            }
        }
    }
    // local lock object into the global lock object for use by other fns.
    if (// thisMethod.getSubSignature().equals("void
    !addedGlobalLockDefs) // <clinit>()") &&
    // thisMethod.getDeclaringClass() ==
    // Scene.v().getMainClass())
    {
        // Either get or add the <clinit> method to the main class
        SootClass mainClass = Scene.v().getMainClass();
        SootMethod clinitMethod = null;
        JimpleBody clinitBody = null;
        Stmt firstStmt = null;
        boolean addingNewClinit = !mainClass.declaresMethod("void <clinit>()");
        if (addingNewClinit) {
            clinitMethod = Scene.v().makeSootMethod("<clinit>", new ArrayList(), VoidType.v(), Modifier.PUBLIC | Modifier.STATIC);
            clinitBody = Jimple.v().newBody(clinitMethod);
            clinitMethod.setActiveBody(clinitBody);
            mainClass.addMethod(clinitMethod);
        } else {
            clinitMethod = mainClass.getMethod("void <clinit>()");
            clinitBody = (JimpleBody) clinitMethod.getActiveBody();
            firstStmt = clinitBody.getFirstNonIdentityStmt();
        }
        PatchingChain<Unit> clinitUnits = clinitBody.getUnits();
        for (int i = 1; i < groups.size(); i++) {
            CriticalSectionGroup tnGroup = groups.get(i);
            // if( useGlobalLock[i - 1] )
            if (!tnGroup.useDynamicLock && !tnGroup.useLocksets) {
                // add local lock obj
                // addedLocalLockObj[i] = true;
                // TODO: add name
                clinitBody.getLocals().add(lockObj[i]);
                // conflict
                // avoidance code
                // assign new object to lock obj
                Stmt newStmt = Jimple.v().newAssignStmt(lockObj[i], Jimple.v().newNewExpr(RefType.v("java.lang.Object")));
                if (addingNewClinit)
                    clinitUnits.add(newStmt);
                else
                    clinitUnits.insertBeforeNoRedirect(newStmt, firstStmt);
                // initialize new object
                SootClass objectClass = Scene.v().loadClassAndSupport("java.lang.Object");
                RefType type = RefType.v(objectClass);
                SootMethod initMethod = objectClass.getMethod("void <init>()");
                Stmt initStmt = Jimple.v().newInvokeStmt(Jimple.v().newSpecialInvokeExpr(lockObj[i], initMethod.makeRef(), Collections.EMPTY_LIST));
                if (addingNewClinit)
                    clinitUnits.add(initStmt);
                else
                    clinitUnits.insertBeforeNoRedirect(initStmt, firstStmt);
                // copy new object to global static lock object (for use by
                // other fns)
                Stmt assignStmt = Jimple.v().newAssignStmt(Jimple.v().newStaticFieldRef(globalLockObj[i].makeRef()), lockObj[i]);
                if (addingNewClinit)
                    clinitUnits.add(assignStmt);
                else
                    clinitUnits.insertBeforeNoRedirect(assignStmt, firstStmt);
            }
        }
        if (addingNewClinit)
            clinitUnits.add(Jimple.v().newReturnVoidStmt());
        addedGlobalLockDefs = true;
    }
    int tempNum = 1;
    // Iterate through all of the transactions in the current method
    Iterator fsIt = fs.iterator();
    Stmt newPrep = null;
    while (fsIt.hasNext()) {
        CriticalSection tn = ((SynchronizedRegionFlowPair) fsIt.next()).tn;
        if (tn.setNumber == -1)
            // this tn should be deleted... for now just skip it!
            continue;
        if (tn.wholeMethod) {
            // remove
            thisMethod.setModifiers(thisMethod.getModifiers() & ~(Modifier.SYNCHRONIZED));
        // synchronized
        // modifier
        // for
        // this
        // method
        }
        // depends on type of locking
        Local clo = null;
        // current synchronized region
        SynchronizedRegion csr = null;
        int lockNum = 0;
        boolean moreLocks = true;
        while (moreLocks) {
            // needed for this transaction, then create one.
            if (tn.group.useDynamicLock) {
                // adds
                Value lock = getLockFor((EquivalentValue) tn.lockObject);
                // needed
                if (lock instanceof Ref) {
                    if (lock instanceof InstanceFieldRef) {
                        InstanceFieldRef ifr = (InstanceFieldRef) lock;
                        if (ifr.getBase() instanceof FakeJimpleLocal)
                            lock = reconstruct(b, units, ifr, (tn.entermonitor != null ? tn.entermonitor : tn.beginning), (tn.entermonitor != null));
                    }
                    if (!b.getLocals().contains(lockObj[tn.setNumber]))
                        b.getLocals().add(lockObj[tn.setNumber]);
                    newPrep = Jimple.v().newAssignStmt(lockObj[tn.setNumber], lock);
                    if (tn.wholeMethod)
                        units.insertBeforeNoRedirect(newPrep, firstUnit);
                    else
                        units.insertBefore(newPrep, tn.entermonitor);
                    clo = lockObj[tn.setNumber];
                } else if (lock instanceof Local)
                    clo = (Local) lock;
                else
                    throw new RuntimeException("Unknown type of lock (" + lock + "): expected Ref or Local");
                csr = tn;
                moreLocks = false;
            } else if (tn.group.useLocksets) {
                // adds
                Value lock = getLockFor((EquivalentValue) tn.lockset.get(lockNum));
                // needed
                if (lock instanceof FieldRef) {
                    if (lock instanceof InstanceFieldRef) {
                        InstanceFieldRef ifr = (InstanceFieldRef) lock;
                        if (ifr.getBase() instanceof FakeJimpleLocal)
                            lock = reconstruct(b, units, ifr, (tn.entermonitor != null ? tn.entermonitor : tn.beginning), (tn.entermonitor != null));
                    }
                    // add a local variable for this lock
                    Local lockLocal = Jimple.v().newLocal("locksetObj" + tempNum, RefType.v("java.lang.Object"));
                    tempNum++;
                    b.getLocals().add(lockLocal);
                    // make it refer to the right lock object
                    newPrep = Jimple.v().newAssignStmt(lockLocal, lock);
                    if (tn.entermonitor != null)
                        units.insertBefore(newPrep, tn.entermonitor);
                    else
                        units.insertBeforeNoRedirect(newPrep, tn.beginning);
                    // use it as the lock
                    clo = lockLocal;
                } else if (lock instanceof Local)
                    clo = (Local) lock;
                else
                    throw new RuntimeException("Unknown type of lock (" + lock + "): expected FieldRef or Local");
                if (lockNum + 1 >= tn.lockset.size())
                    moreLocks = false;
                else
                    moreLocks = true;
                if (lockNum > 0) {
                    SynchronizedRegion nsr = new SynchronizedRegion();
                    nsr.beginning = csr.beginning;
                    for (Pair earlyEnd : csr.earlyEnds) {
                        Stmt earlyExitmonitor = (Stmt) earlyEnd.getO2();
                        // <early
                        nsr.earlyEnds.add(new Pair(earlyExitmonitor, null));
                    // exitmonitor,
                    // null>
                    }
                    // last stmt before exception
                    nsr.last = csr.last;
                    // handling
                    if (csr.end != null) {
                        Stmt endExitmonitor = csr.end.getO2();
                        nsr.after = endExitmonitor;
                    }
                    csr = nsr;
                } else
                    csr = tn;
            } else // global lock
            {
                if (!addedLocalLockObj[tn.setNumber])
                    b.getLocals().add(lockObj[tn.setNumber]);
                addedLocalLockObj[tn.setNumber] = true;
                newPrep = Jimple.v().newAssignStmt(lockObj[tn.setNumber], Jimple.v().newStaticFieldRef(globalLockObj[tn.setNumber].makeRef()));
                if (tn.wholeMethod)
                    units.insertBeforeNoRedirect(newPrep, firstUnit);
                else
                    units.insertBefore(newPrep, tn.entermonitor);
                clo = lockObj[tn.setNumber];
                csr = tn;
                moreLocks = false;
            }
            // monitorenter/monitorexit statements with new ones
            if (true) {
                // Remove old prep stmt
                if (csr.prepStmt != null) {
                // units.remove(clr.prepStmt); // seems to trigger bugs
                // in code generation?
                }
                // Reuse old entermonitor or insert new one, and insert prep
                Stmt newEntermonitor = Jimple.v().newEnterMonitorStmt(clo);
                if (csr.entermonitor != null) {
                    units.insertBefore(newEntermonitor, csr.entermonitor);
                    // redirectTraps(b, clr.entermonitor, newEntermonitor);
                    // // EXPERIMENTAL
                    units.remove(csr.entermonitor);
                    csr.entermonitor = newEntermonitor;
                // units.insertBefore(newEntermonitor, newPrep); //
                // already inserted
                // clr.prepStmt = newPrep;
                } else {
                    units.insertBeforeNoRedirect(newEntermonitor, csr.beginning);
                    csr.entermonitor = newEntermonitor;
                // units.insertBefore(newEntermonitor, newPrep); //
                // already inserted
                // clr.prepStmt = newPrep;
                }
                // For each early end, reuse or insert exitmonitor stmt
                List<Pair<Stmt, Stmt>> newEarlyEnds = new ArrayList<Pair<Stmt, Stmt>>();
                for (Pair<Stmt, Stmt> end : csr.earlyEnds) {
                    Stmt earlyEnd = end.getO1();
                    Stmt exitmonitor = end.getO2();
                    Stmt newExitmonitor = Jimple.v().newExitMonitorStmt(clo);
                    if (exitmonitor != null) {
                        if (newPrep != null) {
                            Stmt tmp = (Stmt) newPrep.clone();
                            // seems
                            units.insertBefore(tmp, exitmonitor);
                        // to
                        // avoid
                        // code
                        // generation
                        // bugs?
                        }
                        units.insertBefore(newExitmonitor, exitmonitor);
                        // redirectTraps(b, exitmonitor, newExitmonitor); //
                        // EXPERIMENTAL
                        units.remove(exitmonitor);
                        newEarlyEnds.add(new Pair<Stmt, Stmt>(earlyEnd, newExitmonitor));
                    } else {
                        if (newPrep != null) {
                            Stmt tmp = (Stmt) newPrep.clone();
                            units.insertBefore(tmp, earlyEnd);
                        }
                        units.insertBefore(newExitmonitor, earlyEnd);
                        newEarlyEnds.add(new Pair<Stmt, Stmt>(earlyEnd, newExitmonitor));
                    }
                }
                csr.earlyEnds = newEarlyEnds;
                // If fallthrough end, reuse or insert goto and exit
                if (csr.after != null) {
                    Stmt newExitmonitor = Jimple.v().newExitMonitorStmt(clo);
                    if (csr.end != null) {
                        Stmt exitmonitor = csr.end.getO2();
                        if (newPrep != null) {
                            Stmt tmp = (Stmt) newPrep.clone();
                            units.insertBefore(tmp, exitmonitor);
                        }
                        units.insertBefore(newExitmonitor, exitmonitor);
                        // redirectTraps(b, exitmonitor, newExitmonitor); //
                        // EXPERIMENTAL
                        units.remove(exitmonitor);
                        csr.end = new Pair<Stmt, Stmt>(csr.end.getO1(), newExitmonitor);
                    } else {
                        if (newPrep != null) {
                            Stmt tmp = (Stmt) newPrep.clone();
                            units.insertBefore(tmp, csr.after);
                        }
                        // steal
                        units.insertBefore(newExitmonitor, csr.after);
                        // jumps
                        // to
                        // end,
                        // send
                        // them
                        // to
                        // monitorexit
                        Stmt newGotoStmt = Jimple.v().newGotoStmt(csr.after);
                        units.insertBeforeNoRedirect(newGotoStmt, csr.after);
                        csr.end = new Pair<Stmt, Stmt>(newGotoStmt, newExitmonitor);
                        csr.last = newGotoStmt;
                    }
                }
                // If exceptional end, reuse it, else insert it and traps
                Stmt newExitmonitor = Jimple.v().newExitMonitorStmt(clo);
                if (csr.exceptionalEnd != null) {
                    Stmt exitmonitor = csr.exceptionalEnd.getO2();
                    if (newPrep != null) {
                        Stmt tmp = (Stmt) newPrep.clone();
                        units.insertBefore(tmp, exitmonitor);
                    }
                    units.insertBefore(newExitmonitor, exitmonitor);
                    units.remove(exitmonitor);
                    csr.exceptionalEnd = new Pair<Stmt, Stmt>(csr.exceptionalEnd.getO1(), newExitmonitor);
                } else {
                    // insert after the last end
                    // last end stmt (not same as last
                    Stmt lastEnd = null;
                    // stmt)
                    if (csr.end != null) {
                        lastEnd = csr.end.getO1();
                    } else {
                        for (Pair earlyEnd : csr.earlyEnds) {
                            Stmt end = (Stmt) earlyEnd.getO1();
                            if (lastEnd == null || (units.contains(lastEnd) && units.contains(end) && units.follows(end, lastEnd)))
                                lastEnd = end;
                        }
                    }
                    if (// || !units.contains(clr.last))
                    csr.last == null)
                        // last stmt and last end are
                        csr.last = lastEnd;
                    // the same
                    if (lastEnd == null)
                        throw new RuntimeException("Lock Region has no ends!  Where should we put the exception handling???");
                    // Add throwable
                    Local throwableLocal = Jimple.v().newLocal("throwableLocal" + (throwableNum++), RefType.v("java.lang.Throwable"));
                    b.getLocals().add(throwableLocal);
                    // Add stmts
                    Stmt newCatch = Jimple.v().newIdentityStmt(throwableLocal, Jimple.v().newCaughtExceptionRef());
                    if (csr.last == null)
                        throw new RuntimeException("WHY IS clr.last NULL???");
                    if (newCatch == null)
                        throw new RuntimeException("WHY IS newCatch NULL???");
                    units.insertAfter(newCatch, csr.last);
                    units.insertAfter(newExitmonitor, newCatch);
                    Stmt newThrow = Jimple.v().newThrowStmt(throwableLocal);
                    units.insertAfter(newThrow, newExitmonitor);
                    // Add traps
                    SootClass throwableClass = Scene.v().loadClassAndSupport("java.lang.Throwable");
                    b.getTraps().addFirst(Jimple.v().newTrap(throwableClass, newExitmonitor, newThrow, newCatch));
                    b.getTraps().addFirst(Jimple.v().newTrap(throwableClass, csr.beginning, lastEnd, newCatch));
                    csr.exceptionalEnd = new Pair<Stmt, Stmt>(newThrow, newExitmonitor);
                }
            }
            lockNum++;
        }
        // deal with waits and notifys
        {
            for (Unit uNotify : tn.notifys) {
                Stmt sNotify = (Stmt) uNotify;
                Stmt newNotify = Jimple.v().newInvokeStmt(Jimple.v().newVirtualInvokeExpr(clo, sNotify.getInvokeExpr().getMethodRef().declaringClass().getMethod("void notifyAll()").makeRef(), Collections.EMPTY_LIST));
                if (newPrep != null) {
                    Stmt tmp = (Stmt) newPrep.clone();
                    units.insertBefore(tmp, sNotify);
                    units.insertBefore(newNotify, tmp);
                } else
                    units.insertBefore(newNotify, sNotify);
                redirectTraps(b, sNotify, newNotify);
                units.remove(sNotify);
            }
            // Replace base object of calls to wait with appropriate lockobj
            for (Unit uWait : tn.waits) {
                Stmt sWait = (Stmt) uWait;
                // WHAT
                ((InstanceInvokeExpr) sWait.getInvokeExpr()).setBase(clo);
                // LOCKS???
                if (newPrep != null)
                    units.insertBefore((Stmt) newPrep.clone(), sWait);
            }
        }
    }
}
Also used : EquivalentValue(soot.EquivalentValue) ArrayList(java.util.ArrayList) Unit(soot.Unit) Stmt(soot.jimple.Stmt) RefType(soot.RefType) Iterator(java.util.Iterator) InstanceFieldRef(soot.jimple.InstanceFieldRef) JimpleBody(soot.jimple.JimpleBody) Pair(soot.toolkits.scalar.Pair) FieldRef(soot.jimple.FieldRef) InstanceFieldRef(soot.jimple.InstanceFieldRef) StaticFieldRef(soot.jimple.StaticFieldRef) FakeJimpleLocal(soot.jimple.toolkits.infoflow.FakeJimpleLocal) Local(soot.Local) SootClass(soot.SootClass) ArrayRef(soot.jimple.ArrayRef) Ref(soot.jimple.Ref) FieldRef(soot.jimple.FieldRef) InstanceFieldRef(soot.jimple.InstanceFieldRef) StaticFieldRef(soot.jimple.StaticFieldRef) EquivalentValue(soot.EquivalentValue) Value(soot.Value) SootMethod(soot.SootMethod) SootField(soot.SootField) FakeJimpleLocal(soot.jimple.toolkits.infoflow.FakeJimpleLocal)

Example 4 with Ref

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

the class DavaBody method javafy_ref.

private void javafy_ref(ValueBox vb) {
    Ref r = (Ref) vb.getValue();
    if (r instanceof StaticFieldRef) {
        SootFieldRef fieldRef = ((StaticFieldRef) r).getFieldRef();
        // addPackage(fieldRef.declaringClass().getJavaPackageName());
        String className = fieldRef.declaringClass().toString();
        String packageName = fieldRef.declaringClass().getJavaPackageName();
        String classPackageName = packageName;
        if (className.lastIndexOf('.') > 0) {
            // 0 doesnt make sense
            classPackageName = className.substring(0, className.lastIndexOf('.'));
        }
        if (!packageName.equals(classPackageName))
            throw new DecompilationException("Unable to retrieve package name for identifier. Please report to developer.");
        addToImportList(className);
        vb.setValue(new DStaticFieldRef(fieldRef, getMethod().getDeclaringClass().getName()));
    } else if (r instanceof ArrayRef) {
        ArrayRef ar = (ArrayRef) r;
        javafy(ar.getBaseBox());
        javafy(ar.getIndexBox());
    } else if (r instanceof InstanceFieldRef) {
        InstanceFieldRef ifr = (InstanceFieldRef) r;
        javafy(ifr.getBaseBox());
        vb.setValue(new DInstanceFieldRef(ifr.getBase(), ifr.getFieldRef(), thisLocals));
    } else if (r instanceof ThisRef) {
        ThisRef tr = (ThisRef) r;
        vb.setValue(new DThisRef((RefType) tr.getType()));
    }
}
Also used : ArrayRef(soot.jimple.ArrayRef) DThisRef(soot.dava.internal.javaRep.DThisRef) CaughtExceptionRef(soot.jimple.CaughtExceptionRef) DThisRef(soot.dava.internal.javaRep.DThisRef) ArrayRef(soot.jimple.ArrayRef) SootMethodRef(soot.SootMethodRef) SootFieldRef(soot.SootFieldRef) DStaticFieldRef(soot.dava.internal.javaRep.DStaticFieldRef) ThisRef(soot.jimple.ThisRef) DInstanceFieldRef(soot.dava.internal.javaRep.DInstanceFieldRef) Ref(soot.jimple.Ref) InstanceFieldRef(soot.jimple.InstanceFieldRef) ParameterRef(soot.jimple.ParameterRef) StaticFieldRef(soot.jimple.StaticFieldRef) DThisRef(soot.dava.internal.javaRep.DThisRef) ThisRef(soot.jimple.ThisRef) DInstanceFieldRef(soot.dava.internal.javaRep.DInstanceFieldRef) DInstanceFieldRef(soot.dava.internal.javaRep.DInstanceFieldRef) InstanceFieldRef(soot.jimple.InstanceFieldRef) DStaticFieldRef(soot.dava.internal.javaRep.DStaticFieldRef) SootFieldRef(soot.SootFieldRef) DStaticFieldRef(soot.dava.internal.javaRep.DStaticFieldRef) StaticFieldRef(soot.jimple.StaticFieldRef)

Aggregations

Ref (soot.jimple.Ref)4 SootMethod (soot.SootMethod)3 Unit (soot.Unit)3 Value (soot.Value)3 ArrayRef (soot.jimple.ArrayRef)3 InstanceFieldRef (soot.jimple.InstanceFieldRef)3 ArrayList (java.util.ArrayList)2 Local (soot.Local)2 RefType (soot.RefType)2 SootClass (soot.SootClass)2 StaticFieldRef (soot.jimple.StaticFieldRef)2 Stmt (soot.jimple.Stmt)2 Pair (soot.toolkits.scalar.Pair)2 FlowFunction (heros.FlowFunction)1 FlowFunctions (heros.FlowFunctions)1 Iterator (java.util.Iterator)1 LinkedHashSet (java.util.LinkedHashSet)1 Set (java.util.Set)1 Body (soot.Body)1 EquivalentValue (soot.EquivalentValue)1