Search in sources :

Example 6 with EnterMonitorStmt

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

the class DexIfTransformer method internalTransform.

@Override
protected void internalTransform(final Body body, String phaseName, Map<String, String> options) {
    final DexDefUseAnalysis localDefs = new DexDefUseAnalysis(body);
    Set<IfStmt> ifSet = getNullIfCandidates(body);
    for (IfStmt ifs : ifSet) {
        ConditionExpr ifCondition = (ConditionExpr) ifs.getCondition();
        Local[] twoIfLocals = new Local[] { (Local) ifCondition.getOp1(), (Local) ifCondition.getOp2() };
        usedAsObject = false;
        for (Local loc : twoIfLocals) {
            Set<Unit> defs = localDefs.collectDefinitionsWithAliases(loc);
            // process normally
            doBreak = false;
            for (Unit u : defs) {
                // put correct local in l
                if (u instanceof DefinitionStmt) {
                    l = (Local) ((DefinitionStmt) u).getLeftOp();
                } else {
                    throw new RuntimeException("ERROR: def can not be something else than Assign or Identity statement! (def: " + u + " class: " + u.getClass() + "");
                }
                // check defs
                u.apply(new // Alex: should also end
                AbstractStmtSwitch() {

                    // as soon as detected
                    // as not used as an
                    // object
                    @Override
                    public void caseAssignStmt(AssignStmt stmt) {
                        Value r = stmt.getRightOp();
                        if (r instanceof FieldRef) {
                            usedAsObject = isObject(((FieldRef) r).getFieldRef().type());
                            if (usedAsObject)
                                doBreak = true;
                            return;
                        } else if (r instanceof ArrayRef) {
                            ArrayRef ar = (ArrayRef) r;
                            if (ar.getType() instanceof UnknownType) {
                                // isObject
                                usedAsObject = stmt.hasTag("ObjectOpTag");
                            // (findArrayType
                            // (g,
                            // localDefs,
                            // localUses,
                            // stmt));
                            } else {
                                usedAsObject = isObject(ar.getType());
                            }
                            if (usedAsObject)
                                doBreak = true;
                            return;
                        } else if (r instanceof StringConstant || r instanceof NewExpr || r instanceof NewArrayExpr) {
                            usedAsObject = true;
                            if (usedAsObject)
                                doBreak = true;
                            return;
                        } else if (r instanceof CastExpr) {
                            usedAsObject = isObject(((CastExpr) r).getCastType());
                            if (usedAsObject)
                                doBreak = true;
                            return;
                        } else if (r instanceof InvokeExpr) {
                            usedAsObject = isObject(((InvokeExpr) r).getType());
                            if (usedAsObject)
                                doBreak = true;
                            return;
                        } else if (r instanceof LengthExpr) {
                            usedAsObject = false;
                            if (usedAsObject)
                                doBreak = true;
                            return;
                        }
                    }

                    @Override
                    public void caseIdentityStmt(IdentityStmt stmt) {
                        if (stmt.getLeftOp() == l) {
                            usedAsObject = isObject(stmt.getRightOp().getType());
                            if (usedAsObject)
                                doBreak = true;
                            return;
                        }
                    }
                });
                if (doBreak)
                    break;
                // check uses
                for (Unit use : localDefs.getUsesOf(l)) {
                    use.apply(new AbstractStmtSwitch() {

                        private boolean examineInvokeExpr(InvokeExpr e) {
                            List<Value> args = e.getArgs();
                            List<Type> argTypes = e.getMethodRef().parameterTypes();
                            assert args.size() == argTypes.size();
                            for (int i = 0; i < args.size(); i++) {
                                if (args.get(i) == l && isObject(argTypes.get(i))) {
                                    return true;
                                }
                            }
                            // check for base
                            SootMethodRef sm = e.getMethodRef();
                            if (!sm.isStatic()) {
                                if (e instanceof AbstractInvokeExpr) {
                                    AbstractInstanceInvokeExpr aiiexpr = (AbstractInstanceInvokeExpr) e;
                                    Value b = aiiexpr.getBase();
                                    if (b == l) {
                                        return true;
                                    }
                                }
                            }
                            return false;
                        }

                        @Override
                        public void caseInvokeStmt(InvokeStmt stmt) {
                            InvokeExpr e = stmt.getInvokeExpr();
                            usedAsObject = examineInvokeExpr(e);
                            if (usedAsObject)
                                doBreak = true;
                            return;
                        }

                        @Override
                        public void caseAssignStmt(AssignStmt stmt) {
                            Value left = stmt.getLeftOp();
                            Value r = stmt.getRightOp();
                            if (left instanceof ArrayRef) {
                                if (((ArrayRef) left).getIndex() == l) {
                                    // doBreak = true;
                                    return;
                                }
                            }
                            // used to assign
                            if (stmt.getRightOp() == l) {
                                Value l = stmt.getLeftOp();
                                if (l instanceof StaticFieldRef && isObject(((StaticFieldRef) l).getFieldRef().type())) {
                                    usedAsObject = true;
                                    if (usedAsObject)
                                        doBreak = true;
                                    return;
                                } else if (l instanceof InstanceFieldRef && isObject(((InstanceFieldRef) l).getFieldRef().type())) {
                                    usedAsObject = true;
                                    if (usedAsObject)
                                        doBreak = true;
                                    return;
                                } else if (l instanceof ArrayRef) {
                                    Type aType = ((ArrayRef) l).getType();
                                    if (aType instanceof UnknownType) {
                                        // isObject(
                                        usedAsObject = stmt.hasTag("ObjectOpTag");
                                    // findArrayType(g,
                                    // localDefs,
                                    // localUses,
                                    // stmt));
                                    } else {
                                        usedAsObject = isObject(aType);
                                    }
                                    if (usedAsObject)
                                        doBreak = true;
                                    return;
                                }
                            }
                            // assignment)
                            if (r instanceof FieldRef) {
                                // isObject(((FieldRef)
                                usedAsObject = true;
                                // r).getFieldRef().type());
                                if (usedAsObject)
                                    doBreak = true;
                                return;
                            } else if (r instanceof ArrayRef) {
                                ArrayRef ar = (ArrayRef) r;
                                if (ar.getBase() == l) {
                                    usedAsObject = true;
                                } else {
                                    // used as index
                                    usedAsObject = false;
                                }
                                if (usedAsObject)
                                    doBreak = true;
                                return;
                            } else if (r instanceof StringConstant || r instanceof NewExpr) {
                                throw new RuntimeException("NOT POSSIBLE StringConstant or NewExpr at " + stmt);
                            } else if (r instanceof NewArrayExpr) {
                                usedAsObject = false;
                                if (usedAsObject)
                                    doBreak = true;
                                return;
                            } else if (r instanceof CastExpr) {
                                usedAsObject = isObject(((CastExpr) r).getCastType());
                                if (usedAsObject)
                                    doBreak = true;
                                return;
                            } else if (r instanceof InvokeExpr) {
                                usedAsObject = examineInvokeExpr((InvokeExpr) stmt.getRightOp());
                                if (usedAsObject)
                                    doBreak = true;
                                return;
                            } else if (r instanceof LengthExpr) {
                                usedAsObject = true;
                                if (usedAsObject)
                                    doBreak = true;
                                return;
                            } else if (r instanceof BinopExpr) {
                                usedAsObject = false;
                                if (usedAsObject)
                                    doBreak = true;
                                return;
                            }
                        }

                        @Override
                        public void caseIdentityStmt(IdentityStmt stmt) {
                            if (stmt.getLeftOp() == l)
                                throw new RuntimeException("IMPOSSIBLE 0");
                        }

                        @Override
                        public void caseEnterMonitorStmt(EnterMonitorStmt stmt) {
                            usedAsObject = stmt.getOp() == l;
                            if (usedAsObject)
                                doBreak = true;
                            return;
                        }

                        @Override
                        public void caseExitMonitorStmt(ExitMonitorStmt stmt) {
                            usedAsObject = stmt.getOp() == l;
                            if (usedAsObject)
                                doBreak = true;
                            return;
                        }

                        @Override
                        public void caseReturnStmt(ReturnStmt stmt) {
                            usedAsObject = stmt.getOp() == l && isObject(body.getMethod().getReturnType());
                            if (usedAsObject)
                                doBreak = true;
                            return;
                        }

                        @Override
                        public void caseThrowStmt(ThrowStmt stmt) {
                            usedAsObject = stmt.getOp() == l;
                            if (usedAsObject)
                                doBreak = true;
                            return;
                        }
                    });
                    if (doBreak)
                        break;
                }
                // for uses
                if (doBreak)
                    break;
            }
            if (// as soon as one def or use refers to an object
            doBreak)
                // be updated
                break;
        }
        // change values
        if (usedAsObject) {
            Set<Unit> defsOp1 = localDefs.collectDefinitionsWithAliases(twoIfLocals[0]);
            Set<Unit> defsOp2 = localDefs.collectDefinitionsWithAliases(twoIfLocals[1]);
            defsOp1.addAll(defsOp2);
            for (Unit u : defsOp1) {
                Stmt s = (Stmt) u;
                // If we have a[x] = 0 and a is an object, we may not conclude 0 -> null
                if (!s.containsArrayRef() || (!defsOp1.contains(s.getArrayRef().getBase()) && !defsOp2.contains(s.getArrayRef().getBase())))
                    replaceWithNull(u);
                Local l = (Local) ((DefinitionStmt) u).getLeftOp();
                for (Unit uuse : localDefs.getUsesOf(l)) {
                    Stmt use = (Stmt) uuse;
                    // If we have a[x] = 0 and a is an object, we may not conclude 0 -> null
                    if (!use.containsArrayRef() || (twoIfLocals[0] != use.getArrayRef().getBase()) && twoIfLocals[1] != use.getArrayRef().getBase())
                        replaceWithNull(use);
                }
            }
        }
    // end if
    }
// for if statements
}
Also used : ExitMonitorStmt(soot.jimple.ExitMonitorStmt) InvokeStmt(soot.jimple.InvokeStmt) AssignStmt(soot.jimple.AssignStmt) Unit(soot.Unit) InvokeStmt(soot.jimple.InvokeStmt) ThrowStmt(soot.jimple.ThrowStmt) IfStmt(soot.jimple.IfStmt) IdentityStmt(soot.jimple.IdentityStmt) EnterMonitorStmt(soot.jimple.EnterMonitorStmt) ReturnStmt(soot.jimple.ReturnStmt) ExitMonitorStmt(soot.jimple.ExitMonitorStmt) Stmt(soot.jimple.Stmt) AssignStmt(soot.jimple.AssignStmt) DefinitionStmt(soot.jimple.DefinitionStmt) ArrayRef(soot.jimple.ArrayRef) AbstractInvokeExpr(soot.jimple.internal.AbstractInvokeExpr) AbstractInstanceInvokeExpr(soot.jimple.internal.AbstractInstanceInvokeExpr) AbstractInvokeExpr(soot.jimple.internal.AbstractInvokeExpr) InvokeExpr(soot.jimple.InvokeExpr) AbstractInstanceInvokeExpr(soot.jimple.internal.AbstractInstanceInvokeExpr) CastExpr(soot.jimple.CastExpr) AbstractStmtSwitch(soot.jimple.AbstractStmtSwitch) InstanceFieldRef(soot.jimple.InstanceFieldRef) List(java.util.List) IdentityStmt(soot.jimple.IdentityStmt) EnterMonitorStmt(soot.jimple.EnterMonitorStmt) FieldRef(soot.jimple.FieldRef) InstanceFieldRef(soot.jimple.InstanceFieldRef) StaticFieldRef(soot.jimple.StaticFieldRef) SootMethodRef(soot.SootMethodRef) LengthExpr(soot.jimple.LengthExpr) Local(soot.Local) StaticFieldRef(soot.jimple.StaticFieldRef) UnknownType(soot.UnknownType) UnknownType(soot.UnknownType) Type(soot.Type) IfStmt(soot.jimple.IfStmt) NewArrayExpr(soot.jimple.NewArrayExpr) ConditionExpr(soot.jimple.ConditionExpr) Value(soot.Value) NewExpr(soot.jimple.NewExpr) StringConstant(soot.jimple.StringConstant) DefinitionStmt(soot.jimple.DefinitionStmt) ReturnStmt(soot.jimple.ReturnStmt) ThrowStmt(soot.jimple.ThrowStmt) BinopExpr(soot.jimple.BinopExpr)

Example 7 with EnterMonitorStmt

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

the class MonitorConverter method convert.

public void convert(DavaBody body) {
    for (AugmentedStmt mas : body.get_MonitorFacts()) {
        MonitorStmt ms = (MonitorStmt) mas.get_Stmt();
        body.addToImportList("soot.dava.toolkits.base.DavaMonitor.DavaMonitor");
        ArrayList arg = new ArrayList();
        arg.add(ms.getOp());
        if (ms instanceof EnterMonitorStmt)
            mas.set_Stmt(new GInvokeStmt(new DVirtualInvokeExpr(new DStaticInvokeExpr(v.makeRef(), new ArrayList()), enter.makeRef(), arg, new HashSet<Object>())));
        else
            mas.set_Stmt(new GInvokeStmt(new DVirtualInvokeExpr(new DStaticInvokeExpr(v.makeRef(), new ArrayList()), exit.makeRef(), arg, new HashSet<Object>())));
    }
}
Also used : DVirtualInvokeExpr(soot.dava.internal.javaRep.DVirtualInvokeExpr) GInvokeStmt(soot.grimp.internal.GInvokeStmt) DStaticInvokeExpr(soot.dava.internal.javaRep.DStaticInvokeExpr) ArrayList(java.util.ArrayList) AugmentedStmt(soot.dava.internal.asg.AugmentedStmt) MonitorStmt(soot.jimple.MonitorStmt) EnterMonitorStmt(soot.jimple.EnterMonitorStmt) EnterMonitorStmt(soot.jimple.EnterMonitorStmt) HashSet(java.util.HashSet)

Example 8 with EnterMonitorStmt

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

the class MonitorEnterInstruction method jimplify.

@Override
public void jimplify(DexBody body) {
    int reg = ((OneRegisterInstruction) instruction).getRegisterA();
    Local object = body.getRegisterLocal(reg);
    EnterMonitorStmt enterMonitorStmt = Jimple.v().newEnterMonitorStmt(object);
    setUnit(enterMonitorStmt);
    addTags(enterMonitorStmt);
    body.add(enterMonitorStmt);
    if (IDalvikTyper.ENABLE_DVKTYPER) {
        // Debug.printDbg(IDalvikTyper.DEBUG, "constraint: "+ enterMonitorStmt);
        DalvikTyper.v().setType(enterMonitorStmt.getOpBox(), RefType.v("java.lang.Object"), true);
    }
}
Also used : OneRegisterInstruction(org.jf.dexlib2.iface.instruction.OneRegisterInstruction) Local(soot.Local) EnterMonitorStmt(soot.jimple.EnterMonitorStmt)

Example 9 with EnterMonitorStmt

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

the class DalvikTyper method typeUntypedConstrantInDiv.

// this is needed because UnuesedStatementTransformer checks types in the div expressions
public void typeUntypedConstrantInDiv(final Body b) {
    for (Unit u : b.getUnits()) {
        StmtSwitch sw = new StmtSwitch() {

            @Override
            public void caseBreakpointStmt(BreakpointStmt stmt) {
            // TODO Auto-generated method stub
            }

            @Override
            public void caseInvokeStmt(InvokeStmt stmt) {
                changeUntypedConstantsInInvoke(stmt.getInvokeExpr());
            }

            @Override
            public void caseAssignStmt(AssignStmt stmt) {
                if (stmt.getRightOp() instanceof NewArrayExpr) {
                    NewArrayExpr nae = (NewArrayExpr) stmt.getRightOp();
                    if (nae.getSize() instanceof UntypedConstant) {
                        UntypedIntOrFloatConstant uc = (UntypedIntOrFloatConstant) nae.getSize();
                        nae.setSize(uc.defineType(IntType.v()));
                    }
                } else if (stmt.getRightOp() instanceof InvokeExpr) {
                    changeUntypedConstantsInInvoke((InvokeExpr) stmt.getRightOp());
                } else if (stmt.getRightOp() instanceof CastExpr) {
                    CastExpr ce = (CastExpr) stmt.getRightOp();
                    if (ce.getOp() instanceof UntypedConstant) {
                        UntypedConstant uc = (UntypedConstant) ce.getOp();
                        // check incoming primitive type
                        for (Tag t : stmt.getTags()) {
                            // Debug.printDbg("assign primitive type from stmt tag: ", stmt, t);
                            if (t instanceof IntOpTag) {
                                ce.setOp(uc.defineType(IntType.v()));
                                return;
                            } else if (t instanceof FloatOpTag) {
                                ce.setOp(uc.defineType(FloatType.v()));
                                return;
                            } else if (t instanceof DoubleOpTag) {
                                ce.setOp(uc.defineType(DoubleType.v()));
                                return;
                            } else if (t instanceof LongOpTag) {
                                ce.setOp(uc.defineType(LongType.v()));
                                return;
                            }
                        }
                        // 0 -> null
                        ce.setOp(uc.defineType(RefType.v("java.lang.Object")));
                    }
                }
                if (stmt.containsArrayRef()) {
                    ArrayRef ar = stmt.getArrayRef();
                    if ((ar.getIndex() instanceof UntypedConstant)) {
                        UntypedIntOrFloatConstant uc = (UntypedIntOrFloatConstant) ar.getIndex();
                        ar.setIndex(uc.toIntConstant());
                    }
                }
                Value r = stmt.getRightOp();
                if (r instanceof DivExpr || r instanceof RemExpr) {
                    // DivExpr de = (DivExpr) r;
                    for (Tag t : stmt.getTags()) {
                        // Debug.printDbg("div stmt tag: ", stmt, t);
                        if (t instanceof IntOpTag) {
                            checkExpr(r, IntType.v());
                            return;
                        } else if (t instanceof FloatOpTag) {
                            checkExpr(r, FloatType.v());
                            return;
                        } else if (t instanceof DoubleOpTag) {
                            checkExpr(r, DoubleType.v());
                            return;
                        } else if (t instanceof LongOpTag) {
                            checkExpr(r, LongType.v());
                            return;
                        }
                    }
                }
            }

            @Override
            public void caseIdentityStmt(IdentityStmt stmt) {
            // TODO Auto-generated method stub
            }

            @Override
            public void caseEnterMonitorStmt(EnterMonitorStmt stmt) {
            // TODO Auto-generated method stub
            }

            @Override
            public void caseExitMonitorStmt(ExitMonitorStmt stmt) {
            // TODO Auto-generated method stub
            }

            @Override
            public void caseGotoStmt(GotoStmt stmt) {
            // TODO Auto-generated method stub
            }

            @Override
            public void caseIfStmt(IfStmt stmt) {
            // TODO Auto-generated method stub
            }

            @Override
            public void caseLookupSwitchStmt(LookupSwitchStmt stmt) {
            // TODO Auto-generated method stub
            }

            @Override
            public void caseNopStmt(NopStmt stmt) {
            // TODO Auto-generated method stub
            }

            @Override
            public void caseRetStmt(RetStmt stmt) {
            // TODO Auto-generated method stub
            }

            @Override
            public void caseReturnStmt(ReturnStmt stmt) {
                if (stmt.getOp() instanceof UntypedConstant) {
                    UntypedConstant uc = (UntypedConstant) stmt.getOp();
                    Type type = b.getMethod().getReturnType();
                    stmt.setOp(uc.defineType(type));
                }
            }

            @Override
            public void caseReturnVoidStmt(ReturnVoidStmt stmt) {
            // TODO Auto-generated method stub
            }

            @Override
            public void caseTableSwitchStmt(TableSwitchStmt stmt) {
            // TODO Auto-generated method stub
            }

            @Override
            public void caseThrowStmt(ThrowStmt stmt) {
                if (stmt.getOp() instanceof UntypedConstant) {
                    UntypedConstant uc = (UntypedConstant) stmt.getOp();
                    stmt.setOp(uc.defineType(RefType.v("java.lang.Object")));
                }
            }

            @Override
            public void defaultCase(Object obj) {
            // TODO Auto-generated method stub
            }
        };
        u.apply(sw);
    }
}
Also used : ExitMonitorStmt(soot.jimple.ExitMonitorStmt) InvokeStmt(soot.jimple.InvokeStmt) AssignStmt(soot.jimple.AssignStmt) ReturnVoidStmt(soot.jimple.ReturnVoidStmt) IntOpTag(soot.dexpler.tags.IntOpTag) RetStmt(soot.jimple.RetStmt) Unit(soot.Unit) LongOpTag(soot.dexpler.tags.LongOpTag) BreakpointStmt(soot.jimple.BreakpointStmt) FloatOpTag(soot.dexpler.tags.FloatOpTag) ArrayRef(soot.jimple.ArrayRef) DoubleOpTag(soot.dexpler.tags.DoubleOpTag) TableSwitchStmt(soot.jimple.TableSwitchStmt) InstanceInvokeExpr(soot.jimple.InstanceInvokeExpr) DynamicInvokeExpr(soot.jimple.DynamicInvokeExpr) InvokeExpr(soot.jimple.InvokeExpr) StaticInvokeExpr(soot.jimple.StaticInvokeExpr) GotoStmt(soot.jimple.GotoStmt) CastExpr(soot.jimple.CastExpr) StmtSwitch(soot.jimple.StmtSwitch) IdentityStmt(soot.jimple.IdentityStmt) EnterMonitorStmt(soot.jimple.EnterMonitorStmt) LookupSwitchStmt(soot.jimple.LookupSwitchStmt) DivExpr(soot.jimple.DivExpr) RefType(soot.RefType) ShortType(soot.ShortType) BooleanType(soot.BooleanType) ByteType(soot.ByteType) Type(soot.Type) UnknownType(soot.UnknownType) DoubleType(soot.DoubleType) FloatType(soot.FloatType) IntType(soot.IntType) CharType(soot.CharType) LongType(soot.LongType) ArrayType(soot.ArrayType) PrimType(soot.PrimType) IfStmt(soot.jimple.IfStmt) NewArrayExpr(soot.jimple.NewArrayExpr) RemExpr(soot.jimple.RemExpr) NopStmt(soot.jimple.NopStmt) Value(soot.Value) LongOpTag(soot.dexpler.tags.LongOpTag) Tag(soot.tagkit.Tag) DoubleOpTag(soot.dexpler.tags.DoubleOpTag) IntOpTag(soot.dexpler.tags.IntOpTag) FloatOpTag(soot.dexpler.tags.FloatOpTag) ReturnStmt(soot.jimple.ReturnStmt) ThrowStmt(soot.jimple.ThrowStmt)

Aggregations

EnterMonitorStmt (soot.jimple.EnterMonitorStmt)9 Unit (soot.Unit)7 ExitMonitorStmt (soot.jimple.ExitMonitorStmt)6 HashSet (java.util.HashSet)5 Local (soot.Local)5 Value (soot.Value)5 IdentityStmt (soot.jimple.IdentityStmt)5 IfStmt (soot.jimple.IfStmt)5 InvokeExpr (soot.jimple.InvokeExpr)5 InvokeStmt (soot.jimple.InvokeStmt)5 ReturnStmt (soot.jimple.ReturnStmt)5 ThrowStmt (soot.jimple.ThrowStmt)5 ArrayList (java.util.ArrayList)4 Type (soot.Type)4 UnknownType (soot.UnknownType)4 ArrayRef (soot.jimple.ArrayRef)4 AssignStmt (soot.jimple.AssignStmt)4 CastExpr (soot.jimple.CastExpr)4 NewArrayExpr (soot.jimple.NewArrayExpr)4 List (java.util.List)3