Search in sources :

Example 21 with BinopExpr

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

the class DavaBody method javafy_binop_expr.

private void javafy_binop_expr(ValueBox vb) {
    BinopExpr boe = (BinopExpr) vb.getValue();
    ValueBox leftOpBox = boe.getOp1Box(), rightOpBox = boe.getOp2Box();
    Value leftOp = leftOpBox.getValue(), rightOp = rightOpBox.getValue();
    if (rightOp instanceof IntConstant) {
        if ((leftOp instanceof IntConstant) == false) {
            javafy(leftOpBox);
            leftOp = leftOpBox.getValue();
            if (boe instanceof ConditionExpr)
                rightOpBox.setValue(DIntConstant.v(((IntConstant) rightOp).value, leftOp.getType()));
            else
                rightOpBox.setValue(DIntConstant.v(((IntConstant) rightOp).value, null));
        }
    } else if (leftOp instanceof IntConstant) {
        javafy(rightOpBox);
        rightOp = rightOpBox.getValue();
        if (boe instanceof ConditionExpr)
            leftOpBox.setValue(DIntConstant.v(((IntConstant) leftOp).value, rightOp.getType()));
        else
            leftOpBox.setValue(DIntConstant.v(((IntConstant) leftOp).value, null));
    } else {
        javafy(rightOpBox);
        rightOp = rightOpBox.getValue();
        javafy(leftOpBox);
        leftOp = leftOpBox.getValue();
    }
    if (boe instanceof CmpExpr)
        vb.setValue(new DCmpExpr(leftOp, rightOp));
    else if (boe instanceof CmplExpr)
        vb.setValue(new DCmplExpr(leftOp, rightOp));
    else if (boe instanceof CmpgExpr)
        vb.setValue(new DCmpgExpr(leftOp, rightOp));
}
Also used : DCmpgExpr(soot.dava.internal.javaRep.DCmpgExpr) ValueBox(soot.ValueBox) DCmpExpr(soot.dava.internal.javaRep.DCmpExpr) CmpExpr(soot.jimple.CmpExpr) ConditionExpr(soot.jimple.ConditionExpr) DCmpgExpr(soot.dava.internal.javaRep.DCmpgExpr) CmpgExpr(soot.jimple.CmpgExpr) Value(soot.Value) IntConstant(soot.jimple.IntConstant) DIntConstant(soot.dava.internal.javaRep.DIntConstant) DCmpExpr(soot.dava.internal.javaRep.DCmpExpr) DCmplExpr(soot.dava.internal.javaRep.DCmplExpr) DCmplExpr(soot.dava.internal.javaRep.DCmplExpr) CmplExpr(soot.jimple.CmplExpr) BinopExpr(soot.jimple.BinopExpr)

Example 22 with BinopExpr

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

the class CP method handleMathematical.

/*
	 * x = b where b is in the before set of the statement as a constant then we
	 * can simply say x = that constant also
	 * 
	 * TODO: DONT WANT TO DO IT:::: If right expr is a unary expression see if
	 * the stuff inside is a Local
	 * 
	 * x = exp1 op exp2 (check if both exp1 and exp2 are int constants
	 * 
	 * killedValuse is either the constant value which left had before this
	 * assignment stmt or null if left was Top or not in the set
	 * 
	 * handle the special case when the inputset could not find a value because
	 * its the killed value //eg. x = x+1 since we top x first we will never get
	 * a match IMPORTANT
	 */
private void handleMathematical(CPFlowSet toReturn, Local left, Value right, Object killedValue) {
    // if right expr is a local or field
    Object value = isANotTopConstantInInputSet(toReturn, right);
    if (value != null) {
        // right was a local or field with a value other than top
        // dont send value SEND A CLONE OF VALUE.....IMPORTANT!!!!
        Object toSend = CPHelper.wrapperClassCloner(value);
        if (toSend != null) {
            addOrUpdate(toReturn, left, toSend);
        }
        // primitive local assigned some value from the right
        return;
    }
    // we could find in the set
    if (right instanceof BinopExpr) {
        Value op1 = ((BinopExpr) right).getOp1();
        Value op2 = ((BinopExpr) right).getOp2();
        Object op1Val = CPHelper.isAConstantValue(op1);
        Object op2Val = CPHelper.isAConstantValue(op2);
        if (op1Val == null)
            op1Val = isANotTopConstantInInputSet(toReturn, op1);
        if (op2Val == null)
            op2Val = isANotTopConstantInInputSet(toReturn, op2);
        if (op1 == left) {
            // System.out.println("\n\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>OP1 is the same as LHS");
            op1Val = killedValue;
        }
        if (op2 == left) {
            // System.out.println("\n\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>OP2 is the same as LHS");
            op2Val = killedValue;
        }
        if (op1Val != null && op2Val != null) {
            // System.out.println("found constant values for both operands of binary expression");
            if (left.getType() instanceof IntType && op1Val instanceof Integer && op2Val instanceof Integer) {
                // only caring about operations on two integers and result
                // is an integer
                int op1IntValue = ((Integer) op1Val).intValue();
                int op2IntValue = ((Integer) op2Val).intValue();
                String tempStr = ((BinopExpr) right).getSymbol();
                if (tempStr.length() > 1) {
                    char symbol = tempStr.charAt(1);
                    // System.out.println("found symbol "+symbol+" for the operands of binary expression");
                    int newValue = 0;
                    boolean set = false;
                    switch(symbol) {
                        case '+':
                            // System.out.println("Adding");
                            newValue = op1IntValue + op2IntValue;
                            set = true;
                            break;
                        case '-':
                            // System.out.println("Subtracting");
                            newValue = op1IntValue - op2IntValue;
                            set = true;
                            break;
                        case '*':
                            // System.out.println("Multiplying");
                            newValue = op1IntValue * op2IntValue;
                            set = true;
                            break;
                    }
                    if (set) {
                        // we have our new value
                        Integer newValueObject = new Integer(newValue);
                        addOrUpdate(toReturn, left, newValueObject);
                        return;
                    }
                }
            }
        } else {
        // System.out.println("atleast one value is not constant so cant simplify expression");
        }
    }
// System.out.println("DefinitionStmt checked right expr for mathematical stuff"+toReturn.toString());
}
Also used : Value(soot.Value) BinopExpr(soot.jimple.BinopExpr) IntType(soot.IntType)

Example 23 with BinopExpr

use of soot.jimple.BinopExpr 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 24 with BinopExpr

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

the class CmpInstruction method jimplify.

@Override
public void jimplify(DexBody body) {
    if (!(instruction instanceof Instruction23x))
        throw new IllegalArgumentException("Expected Instruction23x but got: " + instruction.getClass());
    Instruction23x cmpInstr = (Instruction23x) instruction;
    int dest = cmpInstr.getRegisterA();
    Local first = body.getRegisterLocal(cmpInstr.getRegisterB());
    Local second = body.getRegisterLocal(cmpInstr.getRegisterC());
    // Expr cmpExpr;
    // Type type = null
    Opcode opcode = instruction.getOpcode();
    Expr cmpExpr = null;
    Type type = null;
    switch(opcode) {
        case CMPL_DOUBLE:
            setTag(new DoubleOpTag());
            type = DoubleType.v();
            cmpExpr = Jimple.v().newCmplExpr(first, second);
            break;
        case CMPL_FLOAT:
            setTag(new FloatOpTag());
            type = FloatType.v();
            cmpExpr = Jimple.v().newCmplExpr(first, second);
            break;
        case CMPG_DOUBLE:
            setTag(new DoubleOpTag());
            type = DoubleType.v();
            cmpExpr = Jimple.v().newCmpgExpr(first, second);
            break;
        case CMPG_FLOAT:
            setTag(new FloatOpTag());
            type = FloatType.v();
            cmpExpr = Jimple.v().newCmpgExpr(first, second);
            break;
        case CMP_LONG:
            setTag(new LongOpTag());
            type = LongType.v();
            cmpExpr = Jimple.v().newCmpExpr(first, second);
            break;
        default:
            throw new RuntimeException("no opcode for CMP: " + opcode);
    }
    AssignStmt assign = Jimple.v().newAssignStmt(body.getRegisterLocal(dest), cmpExpr);
    assign.addTag(getTag());
    setUnit(assign);
    addTags(assign);
    body.add(assign);
    if (IDalvikTyper.ENABLE_DVKTYPER) {
        getTag().getName();
        BinopExpr bexpr = (BinopExpr) cmpExpr;
        DalvikTyper.v().setType(bexpr.getOp1Box(), type, true);
        DalvikTyper.v().setType(bexpr.getOp2Box(), type, true);
        DalvikTyper.v().setType(((JAssignStmt) assign).leftBox, IntType.v(), false);
    }
}
Also used : JAssignStmt(soot.jimple.internal.JAssignStmt) AssignStmt(soot.jimple.AssignStmt) Local(soot.Local) Opcode(org.jf.dexlib2.Opcode) LongOpTag(soot.dexpler.tags.LongOpTag) FloatOpTag(soot.dexpler.tags.FloatOpTag) DoubleOpTag(soot.dexpler.tags.DoubleOpTag) DoubleType(soot.DoubleType) FloatType(soot.FloatType) IntType(soot.IntType) Type(soot.Type) LongType(soot.LongType) Expr(soot.jimple.Expr) BinopExpr(soot.jimple.BinopExpr) Instruction23x(org.jf.dexlib2.iface.instruction.formats.Instruction23x) BinopExpr(soot.jimple.BinopExpr)

Example 25 with BinopExpr

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

the class IfTestInstruction method ifStatement.

@Override
protected IfStmt ifStatement(DexBody body) {
    Instruction22t i = (Instruction22t) instruction;
    Local one = body.getRegisterLocal(i.getRegisterA());
    Local other = body.getRegisterLocal(i.getRegisterB());
    BinopExpr condition = getComparisonExpr(one, other);
    IfStmt jif = Jimple.v().newIfStmt(condition, targetInstruction.getUnit());
    // setUnit() is called in ConditionalJumpInstruction
    addTags(jif);
    if (IDalvikTyper.ENABLE_DVKTYPER) {
        // Debug.printDbg(IDalvikTyper.DEBUG, "constraint if: "+ jif +" condition: "+ condition);
        DalvikTyper.v().addConstraint(condition.getOp1Box(), condition.getOp2Box());
    }
    return jif;
}
Also used : Instruction22t(org.jf.dexlib2.iface.instruction.formats.Instruction22t) IfStmt(soot.jimple.IfStmt) Local(soot.Local) BinopExpr(soot.jimple.BinopExpr)

Aggregations

BinopExpr (soot.jimple.BinopExpr)26 Value (soot.Value)21 Local (soot.Local)19 ArrayRef (soot.jimple.ArrayRef)12 CastExpr (soot.jimple.CastExpr)11 NewArrayExpr (soot.jimple.NewArrayExpr)11 NullConstant (soot.jimple.NullConstant)11 Type (soot.Type)10 InstanceFieldRef (soot.jimple.InstanceFieldRef)10 IntConstant (soot.jimple.IntConstant)10 InvokeExpr (soot.jimple.InvokeExpr)10 LengthExpr (soot.jimple.LengthExpr)9 IfStmt (soot.jimple.IfStmt)8 LongConstant (soot.jimple.LongConstant)8 StringConstant (soot.jimple.StringConstant)8 Unit (soot.Unit)7 AssignStmt (soot.jimple.AssignStmt)7 FieldRef (soot.jimple.FieldRef)7 NewExpr (soot.jimple.NewExpr)7 NewMultiArrayExpr (soot.jimple.NewMultiArrayExpr)7