Search in sources :

Example 6 with NeExpr

use of soot.jimple.NeExpr in project robovm by robovm.

the class MethodCompiler method if_.

private void if_(IfStmt stmt) {
    ConditionExpr condition = (ConditionExpr) stmt.getCondition();
    Value op1 = immediate(stmt, (Immediate) condition.getOp1());
    Value op2 = immediate(stmt, (Immediate) condition.getOp2());
    Icmp.Condition c = null;
    if (condition instanceof EqExpr) {
        c = Icmp.Condition.eq;
    } else if (condition instanceof NeExpr) {
        c = Icmp.Condition.ne;
    } else if (condition instanceof GtExpr) {
        c = Icmp.Condition.sgt;
    } else if (condition instanceof LtExpr) {
        c = Icmp.Condition.slt;
    } else if (condition instanceof GeExpr) {
        c = Icmp.Condition.sge;
    } else if (condition instanceof LeExpr) {
        c = Icmp.Condition.sle;
    }
    Variable result = function.newVariable(Type.I1);
    function.add(new Icmp(result, c, op1, op2)).attach(stmt);
    Unit nextUnit = sootMethod.getActiveBody().getUnits().getSuccOf(stmt);
    function.add(new Br(new VariableRef(result), function.newBasicBlockRef(new Label(stmt.getTarget())), function.newBasicBlockRef(new Label(nextUnit)))).attach(stmt);
}
Also used : VariableRef(org.robovm.compiler.llvm.VariableRef) Condition(org.robovm.compiler.llvm.Icmp.Condition) Variable(org.robovm.compiler.llvm.Variable) NeExpr(soot.jimple.NeExpr) Label(org.robovm.compiler.llvm.Label) GtExpr(soot.jimple.GtExpr) LtExpr(soot.jimple.LtExpr) GeExpr(soot.jimple.GeExpr) Unit(soot.Unit) LeExpr(soot.jimple.LeExpr) Br(org.robovm.compiler.llvm.Br) EqExpr(soot.jimple.EqExpr) ConditionExpr(soot.jimple.ConditionExpr) Value(org.robovm.compiler.llvm.Value) Icmp(org.robovm.compiler.llvm.Icmp)

Example 7 with NeExpr

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

the class ConstraintChecker method caseAssignStmt.

public void caseAssignStmt(AssignStmt stmt) {
    Value l = stmt.getLeftOp();
    Value r = stmt.getRightOp();
    TypeNode left = null;
    TypeNode right = null;
    if (l instanceof ArrayRef) {
        ArrayRef ref = (ArrayRef) l;
        Type baset = ((Local) ref.getBase()).getType();
        if (baset instanceof ArrayType) {
            ArrayType base = (ArrayType) baset;
            Value index = ref.getIndex();
            if ((base.numDimensions == 1) && (base.baseType instanceof IntegerType)) {
                left = ClassHierarchy.v().typeNode(base.baseType);
            }
            if (index instanceof Local) {
                if (!ClassHierarchy.v().typeNode(((Local) index).getType()).hasAncestor_1(ClassHierarchy.v().INT)) {
                    if (fix) {
                        ref.setIndex(insertCast((Local) index, IntType.v(), stmt));
                    } else {
                        error("Type Error(5)");
                    }
                }
            }
        }
    } else if (l instanceof Local) {
        if (((Local) l).getType() instanceof IntegerType) {
            left = ClassHierarchy.v().typeNode(((Local) l).getType());
        }
    } else if (l instanceof InstanceFieldRef) {
        InstanceFieldRef ref = (InstanceFieldRef) l;
        if (ref.getFieldRef().type() instanceof IntegerType) {
            left = ClassHierarchy.v().typeNode(ref.getFieldRef().type());
        }
    } else if (l instanceof StaticFieldRef) {
        StaticFieldRef ref = (StaticFieldRef) l;
        if (ref.getFieldRef().type() instanceof IntegerType) {
            left = ClassHierarchy.v().typeNode(ref.getFieldRef().type());
        }
    } else {
        throw new RuntimeException("Unhandled assignment left hand side type: " + l.getClass());
    }
    if (r instanceof ArrayRef) {
        ArrayRef ref = (ArrayRef) r;
        Type baset = ((Local) ref.getBase()).getType();
        if (!(baset instanceof NullType)) {
            ArrayType base = (ArrayType) baset;
            Value index = ref.getIndex();
            if ((base.numDimensions == 1) && (base.baseType instanceof IntegerType)) {
                right = ClassHierarchy.v().typeNode(base.baseType);
            }
            if (index instanceof Local) {
                if (!ClassHierarchy.v().typeNode(((Local) index).getType()).hasAncestor_1(ClassHierarchy.v().INT)) {
                    if (fix) {
                        ref.setIndex(insertCast((Local) index, IntType.v(), stmt));
                    } else {
                        error("Type Error(6)");
                    }
                }
            }
        }
    } else if (r instanceof DoubleConstant) {
    } else if (r instanceof FloatConstant) {
    } else if (r instanceof IntConstant) {
        int value = ((IntConstant) r).value;
        if (value < -32768) {
            right = ClassHierarchy.v().INT;
        } else if (value < -128) {
            right = ClassHierarchy.v().SHORT;
        } else if (value < 0) {
            right = ClassHierarchy.v().BYTE;
        } else if (value < 2) {
            right = ClassHierarchy.v().R0_1;
        } else if (value < 128) {
            right = ClassHierarchy.v().R0_127;
        } else if (value < 32768) {
            right = ClassHierarchy.v().R0_32767;
        } else if (value < 65536) {
            right = ClassHierarchy.v().CHAR;
        } else {
            right = ClassHierarchy.v().INT;
        }
    } else if (r instanceof LongConstant) {
    } else if (r instanceof NullConstant) {
    } else if (r instanceof StringConstant) {
    } else if (r instanceof ClassConstant) {
    } else if (r instanceof BinopExpr) {
        // ******** BINOP EXPR ********
        BinopExpr be = (BinopExpr) r;
        Value lv = be.getOp1();
        Value rv = be.getOp2();
        TypeNode lop = null;
        TypeNode rop = null;
        // ******** LEFT ********
        if (lv instanceof Local) {
            if (((Local) lv).getType() instanceof IntegerType) {
                lop = ClassHierarchy.v().typeNode(((Local) lv).getType());
            }
        } else if (lv instanceof DoubleConstant) {
        } else if (lv instanceof FloatConstant) {
        } else if (lv instanceof IntConstant) {
            int value = ((IntConstant) lv).value;
            if (value < -32768) {
                lop = ClassHierarchy.v().INT;
            } else if (value < -128) {
                lop = ClassHierarchy.v().SHORT;
            } else if (value < 0) {
                lop = ClassHierarchy.v().BYTE;
            } else if (value < 2) {
                lop = ClassHierarchy.v().R0_1;
            } else if (value < 128) {
                lop = ClassHierarchy.v().R0_127;
            } else if (value < 32768) {
                lop = ClassHierarchy.v().R0_32767;
            } else if (value < 65536) {
                lop = ClassHierarchy.v().CHAR;
            } else {
                lop = ClassHierarchy.v().INT;
            }
        } else if (lv instanceof LongConstant) {
        } else if (lv instanceof NullConstant) {
        } else if (lv instanceof StringConstant) {
        } else if (lv instanceof ClassConstant) {
        } else {
            throw new RuntimeException("Unhandled binary expression left operand type: " + lv.getClass());
        }
        // ******** RIGHT ********
        if (rv instanceof Local) {
            if (((Local) rv).getType() instanceof IntegerType) {
                rop = ClassHierarchy.v().typeNode(((Local) rv).getType());
            }
        } else if (rv instanceof DoubleConstant) {
        } else if (rv instanceof FloatConstant) {
        } else if (rv instanceof IntConstant) {
            int value = ((IntConstant) rv).value;
            if (value < -32768) {
                rop = ClassHierarchy.v().INT;
            } else if (value < -128) {
                rop = ClassHierarchy.v().SHORT;
            } else if (value < 0) {
                rop = ClassHierarchy.v().BYTE;
            } else if (value < 2) {
                rop = ClassHierarchy.v().R0_1;
            } else if (value < 128) {
                rop = ClassHierarchy.v().R0_127;
            } else if (value < 32768) {
                rop = ClassHierarchy.v().R0_32767;
            } else if (value < 65536) {
                rop = ClassHierarchy.v().CHAR;
            } else {
                rop = ClassHierarchy.v().INT;
            }
        } else if (rv instanceof LongConstant) {
        } else if (rv instanceof NullConstant) {
        } else if (rv instanceof StringConstant) {
        } else if (rv instanceof ClassConstant) {
        } else {
            throw new RuntimeException("Unhandled binary expression right operand type: " + rv.getClass());
        }
        if ((be instanceof AddExpr) || (be instanceof SubExpr) || (be instanceof MulExpr) || (be instanceof DivExpr) || (be instanceof RemExpr)) {
            if (lop != null && rop != null) {
                if (!lop.hasAncestor_1(ClassHierarchy.v().INT)) {
                    if (fix) {
                        be.setOp1(insertCast(be.getOp1(), getTypeForCast(lop), IntType.v(), stmt));
                    } else {
                        error("Type Error(7)");
                    }
                }
                if (!rop.hasAncestor_1(ClassHierarchy.v().INT)) {
                    if (fix) {
                        be.setOp2(insertCast(be.getOp2(), getTypeForCast(rop), IntType.v(), stmt));
                    } else {
                        error("Type Error(8)");
                    }
                }
            }
            right = ClassHierarchy.v().INT;
        } else if ((be instanceof AndExpr) || (be instanceof OrExpr) || (be instanceof XorExpr)) {
            if (lop != null && rop != null) {
                TypeNode lca = lop.lca_1(rop);
                if (lca == ClassHierarchy.v().TOP) {
                    if (fix) {
                        if (!lop.hasAncestor_1(ClassHierarchy.v().INT)) {
                            be.setOp1(insertCast(be.getOp1(), getTypeForCast(lop), getTypeForCast(rop), stmt));
                            lca = rop;
                        }
                        if (!rop.hasAncestor_1(ClassHierarchy.v().INT)) {
                            be.setOp2(insertCast(be.getOp2(), getTypeForCast(rop), getTypeForCast(lop), stmt));
                            lca = lop;
                        }
                    } else {
                        error("Type Error(11)");
                    }
                }
                right = lca;
            }
        } else if (be instanceof ShlExpr) {
            if (lop != null) {
                if (!lop.hasAncestor_1(ClassHierarchy.v().INT)) {
                    if (fix) {
                        be.setOp1(insertCast(be.getOp1(), getTypeForCast(lop), IntType.v(), stmt));
                    } else {
                        error("Type Error(9)");
                    }
                }
            }
            if (!rop.hasAncestor_1(ClassHierarchy.v().INT)) {
                if (fix) {
                    be.setOp2(insertCast(be.getOp2(), getTypeForCast(rop), IntType.v(), stmt));
                } else {
                    error("Type Error(10)");
                }
            }
            right = (lop == null) ? null : ClassHierarchy.v().INT;
        } else if ((be instanceof ShrExpr) || (be instanceof UshrExpr)) {
            if (lop != null) {
                if (!lop.hasAncestor_1(ClassHierarchy.v().INT)) {
                    if (fix) {
                        be.setOp1(insertCast(be.getOp1(), getTypeForCast(lop), ByteType.v(), stmt));
                        lop = ClassHierarchy.v().BYTE;
                    } else {
                        error("Type Error(9)");
                    }
                }
            }
            if (!rop.hasAncestor_1(ClassHierarchy.v().INT)) {
                if (fix) {
                    be.setOp2(insertCast(be.getOp2(), getTypeForCast(rop), IntType.v(), stmt));
                } else {
                    error("Type Error(10)");
                }
            }
            right = lop;
        } else if ((be instanceof CmpExpr) || (be instanceof CmpgExpr) || (be instanceof CmplExpr)) {
            right = ClassHierarchy.v().BYTE;
        } else if ((be instanceof EqExpr) || (be instanceof GeExpr) || (be instanceof GtExpr) || (be instanceof LeExpr) || (be instanceof LtExpr) || (be instanceof NeExpr)) {
            if (rop != null) {
                TypeNode lca = lop.lca_1(rop);
                if (lca == ClassHierarchy.v().TOP) {
                    if (fix) {
                        if (!lop.hasAncestor_1(ClassHierarchy.v().INT)) {
                            be.setOp1(insertCast(be.getOp1(), getTypeForCast(lop), getTypeForCast(rop), stmt));
                        }
                        if (!rop.hasAncestor_1(ClassHierarchy.v().INT)) {
                            be.setOp2(insertCast(be.getOp2(), getTypeForCast(rop), getTypeForCast(lop), stmt));
                        }
                    } else {
                        error("Type Error(11)");
                    }
                }
            }
            right = ClassHierarchy.v().BOOLEAN;
        } else {
            throw new RuntimeException("Unhandled binary expression type: " + be.getClass());
        }
    } else if (r instanceof CastExpr) {
        CastExpr ce = (CastExpr) r;
        if (ce.getCastType() instanceof IntegerType) {
            right = ClassHierarchy.v().typeNode(ce.getCastType());
        }
    } else if (r instanceof InstanceOfExpr) {
        right = ClassHierarchy.v().BOOLEAN;
    } else if (r instanceof InvokeExpr) {
        InvokeExpr ie = (InvokeExpr) r;
        handleInvokeExpr(ie, stmt);
        if (ie.getMethodRef().returnType() instanceof IntegerType) {
            right = ClassHierarchy.v().typeNode(ie.getMethodRef().returnType());
        }
    } else if (r instanceof NewArrayExpr) {
        NewArrayExpr nae = (NewArrayExpr) r;
        Value size = nae.getSize();
        if (size instanceof Local) {
            if (!ClassHierarchy.v().typeNode(((Local) size).getType()).hasAncestor_1(ClassHierarchy.v().INT)) {
                if (fix) {
                    nae.setSize(insertCast((Local) size, IntType.v(), stmt));
                } else {
                    error("Type Error(12)");
                }
            }
        }
    } else if (r instanceof NewExpr) {
    } else if (r instanceof NewMultiArrayExpr) {
        NewMultiArrayExpr nmae = (NewMultiArrayExpr) r;
        for (int i = 0; i < nmae.getSizeCount(); i++) {
            Value size = nmae.getSize(i);
            if (size instanceof Local) {
                if (!ClassHierarchy.v().typeNode(((Local) size).getType()).hasAncestor_1(ClassHierarchy.v().INT)) {
                    if (fix) {
                        nmae.setSize(i, insertCast((Local) size, IntType.v(), stmt));
                    } else {
                        error("Type Error(13)");
                    }
                }
            }
        }
    } else if (r instanceof LengthExpr) {
        right = ClassHierarchy.v().INT;
    } else if (r instanceof NegExpr) {
        NegExpr ne = (NegExpr) r;
        if (ne.getOp() instanceof Local) {
            Local local = (Local) ne.getOp();
            if (local.getType() instanceof IntegerType) {
                TypeNode ltype = ClassHierarchy.v().typeNode(local.getType());
                if (!ltype.hasAncestor_1(ClassHierarchy.v().INT)) {
                    if (fix) {
                        ne.setOp(insertCast(local, IntType.v(), stmt));
                        ltype = ClassHierarchy.v().BYTE;
                    } else {
                        error("Type Error(14)");
                    }
                }
                right = (ltype == ClassHierarchy.v().CHAR) ? ClassHierarchy.v().INT : ltype;
            }
        } else if (ne.getOp() instanceof DoubleConstant) {
        } else if (ne.getOp() instanceof FloatConstant) {
        } else if (ne.getOp() instanceof IntConstant) {
            right = ClassHierarchy.v().INT;
        } else if (ne.getOp() instanceof LongConstant) {
        } else {
            throw new RuntimeException("Unhandled neg expression operand type: " + ne.getOp().getClass());
        }
    } else if (r instanceof Local) {
        Local local = (Local) r;
        if (local.getType() instanceof IntegerType) {
            right = ClassHierarchy.v().typeNode(local.getType());
        }
    } else if (r instanceof InstanceFieldRef) {
        InstanceFieldRef ref = (InstanceFieldRef) r;
        if (ref.getFieldRef().type() instanceof IntegerType) {
            right = ClassHierarchy.v().typeNode(ref.getFieldRef().type());
        }
    } else if (r instanceof StaticFieldRef) {
        StaticFieldRef ref = (StaticFieldRef) r;
        if (ref.getFieldRef().type() instanceof IntegerType) {
            right = ClassHierarchy.v().typeNode(ref.getFieldRef().type());
        }
    } else {
        throw new RuntimeException("Unhandled assignment right hand side type: " + r.getClass());
    }
    if (left != null && right != null) {
        if (!right.hasAncestor_1(left)) {
            if (fix) {
                stmt.setRightOp(insertCast(stmt.getRightOp(), getTypeForCast(right), getTypeForCast(left), stmt));
            } else {
                error("Type Error(15)");
            }
        }
    }
}
Also used : MulExpr(soot.jimple.MulExpr) AndExpr(soot.jimple.AndExpr) DoubleConstant(soot.jimple.DoubleConstant) NewMultiArrayExpr(soot.jimple.NewMultiArrayExpr) FloatConstant(soot.jimple.FloatConstant) GtExpr(soot.jimple.GtExpr) LtExpr(soot.jimple.LtExpr) NegExpr(soot.jimple.NegExpr) GeExpr(soot.jimple.GeExpr) UshrExpr(soot.jimple.UshrExpr) LeExpr(soot.jimple.LeExpr) ArrayRef(soot.jimple.ArrayRef) ArrayType(soot.ArrayType) DynamicInvokeExpr(soot.jimple.DynamicInvokeExpr) InvokeExpr(soot.jimple.InvokeExpr) InstanceFieldRef(soot.jimple.InstanceFieldRef) CastExpr(soot.jimple.CastExpr) IntConstant(soot.jimple.IntConstant) ShlExpr(soot.jimple.ShlExpr) LongConstant(soot.jimple.LongConstant) XorExpr(soot.jimple.XorExpr) NeExpr(soot.jimple.NeExpr) LengthExpr(soot.jimple.LengthExpr) SubExpr(soot.jimple.SubExpr) Local(soot.Local) NullConstant(soot.jimple.NullConstant) AddExpr(soot.jimple.AddExpr) InstanceOfExpr(soot.jimple.InstanceOfExpr) OrExpr(soot.jimple.OrExpr) StaticFieldRef(soot.jimple.StaticFieldRef) IntegerType(soot.IntegerType) ShortType(soot.ShortType) BooleanType(soot.BooleanType) ByteType(soot.ByteType) Type(soot.Type) IntType(soot.IntType) NullType(soot.NullType) ArrayType(soot.ArrayType) IntegerType(soot.IntegerType) DivExpr(soot.jimple.DivExpr) NewArrayExpr(soot.jimple.NewArrayExpr) RemExpr(soot.jimple.RemExpr) ShrExpr(soot.jimple.ShrExpr) CmpExpr(soot.jimple.CmpExpr) EqExpr(soot.jimple.EqExpr) CmpgExpr(soot.jimple.CmpgExpr) Value(soot.Value) NewExpr(soot.jimple.NewExpr) NullType(soot.NullType) StringConstant(soot.jimple.StringConstant) CmplExpr(soot.jimple.CmplExpr) ClassConstant(soot.jimple.ClassConstant) BinopExpr(soot.jimple.BinopExpr)

Example 8 with NeExpr

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

the class DexBody method jimplify.

/**
 * Return the jimple equivalent of this body.
 *
 * @param m
 *            the SootMethod that contains this body
 */
public Body jimplify(Body b, SootMethod m) {
    final Jimple jimple = Jimple.v();
    final UnknownType unknownType = UnknownType.v();
    final NullConstant nullConstant = NullConstant.v();
    final Options options = Options.v();
    /*
		 * Timer t_whole_jimplification = new Timer(); Timer t_num = new
		 * Timer(); Timer t_null = new Timer();
		 * 
		 * t_whole_jimplification.start();
		 */
    jBody = (JimpleBody) b;
    deferredInstructions = new ArrayList<DeferableInstruction>();
    instructionsToRetype = new HashSet<RetypeableInstruction>();
    if (IDalvikTyper.ENABLE_DVKTYPER) {
        DalvikTyper.v().clear();
    }
    // process method parameters and generate Jimple locals from Dalvik
    // registers
    List<Local> paramLocals = new LinkedList<Local>();
    if (!isStatic) {
        int thisRegister = numRegisters - numParameterRegisters - 1;
        // generateLocal(UnknownType.v());
        Local thisLocal = jimple.newLocal("$u" + thisRegister, unknownType);
        jBody.getLocals().add(thisLocal);
        registerLocals[thisRegister] = thisLocal;
        JIdentityStmt idStmt = (JIdentityStmt) jimple.newIdentityStmt(thisLocal, jimple.newThisRef(declaringClassType));
        add(idStmt);
        paramLocals.add(thisLocal);
        if (IDalvikTyper.ENABLE_DVKTYPER) {
            DalvikTyper.v().setType(idStmt.leftBox, jBody.getMethod().getDeclaringClass().getType(), false);
        }
    }
    {
        // index of parameter type
        int i = 0;
        // index
        int parameterRegister = numRegisters - numParameterRegisters;
        // register
        for (Type t : parameterTypes) {
            // may
            Local gen = jimple.newLocal("$u" + parameterRegister, unknownType);
            // only
            // use
            // UnknownType
            // here
            // because
            // the
            // local
            // may
            // be
            // reused
            // with
            // a
            // different
            // type
            // later
            // (before
            // splitting)
            jBody.getLocals().add(gen);
            registerLocals[parameterRegister] = gen;
            JIdentityStmt idStmt = (JIdentityStmt) jimple.newIdentityStmt(gen, jimple.newParameterRef(t, i++));
            add(idStmt);
            paramLocals.add(gen);
            if (IDalvikTyper.ENABLE_DVKTYPER) {
                DalvikTyper.v().setType(idStmt.leftBox, t, false);
            }
            // used later in the Dalvik bytecode
            if (t instanceof LongType || t instanceof DoubleType) {
                parameterRegister++;
                // may
                Local g = jimple.newLocal("$u" + parameterRegister, unknownType);
                // only
                // use
                // UnknownType
                // here
                // because
                // the
                // local
                // may
                // be
                // reused
                // with
                // a
                // different
                // type
                // later
                // (before
                // splitting)
                jBody.getLocals().add(g);
                registerLocals[parameterRegister] = g;
            }
            parameterRegister++;
        }
    }
    for (int i = 0; i < (numRegisters - numParameterRegisters - (isStatic ? 0 : 1)); i++) {
        registerLocals[i] = jimple.newLocal("$u" + i, unknownType);
        jBody.getLocals().add(registerLocals[i]);
    }
    // add local to store intermediate results
    storeResultLocal = jimple.newLocal("$u-1", unknownType);
    jBody.getLocals().add(storeResultLocal);
    // process bytecode instructions
    final boolean isOdex = dexFile instanceof DexBackedDexFile ? ((DexBackedDexFile) dexFile).isOdexFile() : false;
    ClassPath cp = null;
    if (isOdex) {
        String[] sootClasspath = options.soot_classpath().split(File.pathSeparator);
        List<String> classpathList = new ArrayList<String>();
        for (String str : sootClasspath) classpathList.add(str);
        try {
            ClassPathResolver resolver = new ClassPathResolver(classpathList, classpathList, classpathList, dexFile);
            cp = new ClassPath(resolver.getResolvedClassProviders().toArray(new ClassProvider[0]));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    int prevLineNumber = -1;
    for (DexlibAbstractInstruction instruction : instructions) {
        if (isOdex && instruction instanceof OdexInstruction)
            ((OdexInstruction) instruction).deOdex(dexFile, method, cp);
        if (dangling != null) {
            dangling.finalize(this, instruction);
            dangling = null;
        }
        instruction.jimplify(this);
        if (instruction.getLineNumber() > 0)
            prevLineNumber = instruction.getLineNumber();
        else {
            instruction.setLineNumber(prevLineNumber);
        }
    }
    for (DeferableInstruction instruction : deferredInstructions) {
        instruction.deferredJimplify(this);
    }
    if (tries != null)
        addTraps();
    int prevLn = -1;
    final boolean keepLineNumber = options.keep_line_number();
    for (DexlibAbstractInstruction instruction : instructions) {
        Unit unit = instruction.getUnit();
        int lineNumber = unit.getJavaSourceStartLineNumber();
        if (keepLineNumber && lineNumber < 0) {
            if (prevLn >= 0) {
                unit.addTag(new LineNumberTag(prevLn));
                unit.addTag(new SourceLineNumberTag(prevLn));
            }
        } else {
            prevLn = lineNumber;
        }
    }
    // At this point Jimple code is generated
    // Cleaning...
    instructions = null;
    // registerLocals = null;
    // storeResultLocal = null;
    instructionAtAddress.clear();
    // localGenerator = null;
    deferredInstructions = null;
    // instructionsToRetype = null;
    dangling = null;
    tries = null;
    /*
		 * We eliminate dead code. Dead code has been shown to occur under the
		 * following circumstances.
		 *
		 * 0006ec: 0d00 |00a2: move-exception v0 ... 0006f2: 0d00 |00a5:
		 * move-exception v0 ... 0x0041 - 0x008a Ljava/lang/Throwable; -> 0x00a5
		 * <any> -> 0x00a2
		 * 
		 * Here there are two traps both over the same region. But the same
		 * always fires, hence rendering the code at a2 unreachable. Dead code
		 * yields problems during local splitting because locals within dead
		 * code will not be split. Hence we remove all dead code here.
		 */
    // Fix traps that do not catch exceptions
    DexTrapStackFixer.v().transform(jBody);
    // Sort out jump chains
    DexJumpChainShortener.v().transform(jBody);
    // Make sure that we don't have any overlapping uses due to returns
    DexReturnInliner.v().transform(jBody);
    // Shortcut: Reduce array initializations
    DexArrayInitReducer.v().transform(jBody);
    // split first to find undefined uses
    getLocalSplitter().transform(jBody);
    // Remove dead code and the corresponding locals before assigning types
    getUnreachableCodeEliminator().transform(jBody);
    DeadAssignmentEliminator.v().transform(jBody);
    UnusedLocalEliminator.v().transform(jBody);
    for (RetypeableInstruction i : instructionsToRetype) i.retype(jBody);
    if (IDalvikTyper.ENABLE_DVKTYPER) {
        DexReturnValuePropagator.v().transform(jBody);
        getCopyPopagator().transform(jBody);
        DexNullThrowTransformer.v().transform(jBody);
        DalvikTyper.v().typeUntypedConstrantInDiv(jBody);
        DeadAssignmentEliminator.v().transform(jBody);
        UnusedLocalEliminator.v().transform(jBody);
        DalvikTyper.v().assignType(jBody);
        // jBody.validate();
        jBody.validateUses();
        jBody.validateValueBoxes();
    // jBody.checkInit();
    // Validate.validateArrays(jBody);
    // jBody.checkTypes();
    // jBody.checkLocals();
    } else {
        // t_num.start();
        DexNumTransformer.v().transform(jBody);
        // t_num.end();
        DexReturnValuePropagator.v().transform(jBody);
        getCopyPopagator().transform(jBody);
        DexNullThrowTransformer.v().transform(jBody);
        // t_null.start();
        DexNullTransformer.v().transform(jBody);
        // t_null.end();
        DexIfTransformer.v().transform(jBody);
        DeadAssignmentEliminator.v().transform(jBody);
        UnusedLocalEliminator.v().transform(jBody);
        // DexRefsChecker.v().transform(jBody);
        DexNullArrayRefTransformer.v().transform(jBody);
    }
    if (IDalvikTyper.ENABLE_DVKTYPER) {
        for (Local l : jBody.getLocals()) {
            l.setType(unknownType);
        }
    }
    // Remove "instanceof" checks on the null constant
    DexNullInstanceofTransformer.v().transform(jBody);
    TypeAssigner.v().transform(jBody);
    final RefType objectType = RefType.v("java.lang.Object");
    if (IDalvikTyper.ENABLE_DVKTYPER) {
        for (Unit u : jBody.getUnits()) {
            if (u instanceof IfStmt) {
                ConditionExpr expr = (ConditionExpr) ((IfStmt) u).getCondition();
                if (((expr instanceof EqExpr) || (expr instanceof NeExpr))) {
                    Value op1 = expr.getOp1();
                    Value op2 = expr.getOp2();
                    if (op1 instanceof Constant && op2 instanceof Local) {
                        Local l = (Local) op2;
                        Type ltype = l.getType();
                        if (ltype instanceof PrimType)
                            continue;
                        if (// by default
                        !(op1 instanceof IntConstant))
                            // in Dalvik
                            continue;
                        IntConstant icst = (IntConstant) op1;
                        int val = icst.value;
                        if (val != 0)
                            continue;
                        expr.setOp1(nullConstant);
                    } else if (op1 instanceof Local && op2 instanceof Constant) {
                        Local l = (Local) op1;
                        Type ltype = l.getType();
                        if (ltype instanceof PrimType)
                            continue;
                        if (// by default
                        !(op2 instanceof IntConstant))
                            // in Dalvik
                            continue;
                        IntConstant icst = (IntConstant) op2;
                        int val = icst.value;
                        if (val != 0)
                            continue;
                        expr.setOp2(nullConstant);
                    } else if (op1 instanceof Local && op2 instanceof Local) {
                    // nothing to do
                    } else if (op1 instanceof Constant && op2 instanceof Constant) {
                        if (op1 instanceof NullConstant && op2 instanceof NumericConstant) {
                            IntConstant nc = (IntConstant) op2;
                            if (nc.value != 0)
                                throw new RuntimeException("expected value 0 for int constant. Got " + expr);
                            expr.setOp2(NullConstant.v());
                        } else if (op2 instanceof NullConstant && op1 instanceof NumericConstant) {
                            IntConstant nc = (IntConstant) op1;
                            if (nc.value != 0)
                                throw new RuntimeException("expected value 0 for int constant. Got " + expr);
                            expr.setOp1(nullConstant);
                        }
                    } else {
                        throw new RuntimeException("error: do not handle if: " + u);
                    }
                }
            }
        }
        // For null_type locals: replace their use by NullConstant()
        List<ValueBox> uses = jBody.getUseBoxes();
        // List<ValueBox> defs = jBody.getDefBoxes();
        List<ValueBox> toNullConstantify = new ArrayList<ValueBox>();
        List<Local> toRemove = new ArrayList<Local>();
        for (Local l : jBody.getLocals()) {
            if (l.getType() instanceof NullType) {
                toRemove.add(l);
                for (ValueBox vb : uses) {
                    Value v = vb.getValue();
                    if (v == l)
                        toNullConstantify.add(vb);
                }
            }
        }
        for (ValueBox vb : toNullConstantify) {
            System.out.println("replace valuebox '" + vb + " with null constant");
            vb.setValue(nullConstant);
        }
        for (Local l : toRemove) {
            System.out.println("removing null_type local " + l);
            l.setType(objectType);
        }
    }
    // We pack locals that are not used in overlapping regions. This may
    // again lead to unused locals which we have to remove.
    LocalPacker.v().transform(jBody);
    UnusedLocalEliminator.v().transform(jBody);
    LocalNameStandardizer.v().transform(jBody);
    // on the fly.
    if (options.wrong_staticness() == Options.wrong_staticness_fix) {
        FieldStaticnessCorrector.v().transform(jBody);
        MethodStaticnessCorrector.v().transform(jBody);
    }
    // Inline PackManager.v().getPack("jb").apply(jBody);
    // Keep only transformations that have not been done
    // at this point.
    TrapTightener.v().transform(jBody);
    TrapMinimizer.v().transform(jBody);
    // LocalSplitter.v().transform(jBody);
    Aggregator.v().transform(jBody);
    // UnusedLocalEliminator.v().transform(jBody);
    // TypeAssigner.v().transform(jBody);
    // LocalPacker.v().transform(jBody);
    // LocalNameStandardizer.v().transform(jBody);
    // Remove if (null == null) goto x else <madness>. We can only do this
    // after we have run the constant propagation as we might not be able
    // to statically decide the conditions earlier.
    ConditionalBranchFolder.v().transform(jBody);
    // Remove unnecessary typecasts
    ConstantCastEliminator.v().transform(jBody);
    IdentityCastEliminator.v().transform(jBody);
    // Remove unnecessary logic operations
    IdentityOperationEliminator.v().transform(jBody);
    // We need to run this transformer since the conditional branch folder
    // might have rendered some code unreachable (well, it was unreachable
    // before as well, but we didn't know).
    UnreachableCodeEliminator.v().transform(jBody);
    // Not sure whether we need this even though we do it earlier on as
    // the earlier pass does not have type information
    // CopyPropagator.v().transform(jBody);
    // we might have gotten new dead assignments and unused locals through
    // copy propagation and unreachable code elimination, so we have to do
    // this again
    DeadAssignmentEliminator.v().transform(jBody);
    UnusedLocalEliminator.v().transform(jBody);
    NopEliminator.v().transform(jBody);
    // Remove unnecessary chains of return statements
    DexReturnPacker.v().transform(jBody);
    for (Unit u : jBody.getUnits()) {
        if (u instanceof AssignStmt) {
            AssignStmt ass = (AssignStmt) u;
            if (ass.getRightOp() instanceof CastExpr) {
                CastExpr c = (CastExpr) ass.getRightOp();
                if (c.getType() instanceof NullType) {
                    ass.setRightOp(nullConstant);
                }
            }
        }
        if (u instanceof DefinitionStmt) {
            DefinitionStmt def = (DefinitionStmt) u;
            // we must manually fix the hierarchy
            if (def.getLeftOp() instanceof Local && def.getRightOp() instanceof CaughtExceptionRef) {
                Type t = def.getLeftOp().getType();
                if (t instanceof RefType) {
                    RefType rt = (RefType) t;
                    if (rt.getSootClass().isPhantom() && !rt.getSootClass().hasSuperclass() && !rt.getSootClass().getName().equals("java.lang.Throwable"))
                        rt.getSootClass().setSuperclass(Scene.v().getSootClass("java.lang.Throwable"));
                }
            }
        }
    }
    // 
    for (Local l : jBody.getLocals()) {
        Type t = l.getType();
        if (t instanceof NullType) {
            l.setType(objectType);
        }
    }
    return jBody;
}
Also used : Options(soot.options.Options) ClassPath(org.jf.dexlib2.analysis.ClassPath) LongType(soot.LongType) CaughtExceptionRef(soot.jimple.CaughtExceptionRef) NullConstant(soot.jimple.NullConstant) Constant(soot.jimple.Constant) IntConstant(soot.jimple.IntConstant) NumericConstant(soot.jimple.NumericConstant) AssignStmt(soot.jimple.AssignStmt) ArrayList(java.util.ArrayList) Unit(soot.Unit) RetypeableInstruction(soot.dexpler.instructions.RetypeableInstruction) RefType(soot.RefType) LineNumberTag(soot.tagkit.LineNumberTag) SourceLineNumberTag(soot.tagkit.SourceLineNumberTag) CastExpr(soot.jimple.CastExpr) PrimType(soot.PrimType) IntConstant(soot.jimple.IntConstant) DeferableInstruction(soot.dexpler.instructions.DeferableInstruction) DexBackedDexFile(org.jf.dexlib2.dexbacked.DexBackedDexFile) ClassPathResolver(org.jf.dexlib2.analysis.ClassPathResolver) DexlibAbstractInstruction(soot.dexpler.instructions.DexlibAbstractInstruction) NeExpr(soot.jimple.NeExpr) JIdentityStmt(soot.jimple.internal.JIdentityStmt) NullConstant(soot.jimple.NullConstant) Local(soot.Local) IOException(java.io.IOException) LinkedList(java.util.LinkedList) UnknownType(soot.UnknownType) RefType(soot.RefType) Type(soot.Type) UnknownType(soot.UnknownType) DoubleType(soot.DoubleType) LongType(soot.LongType) NullType(soot.NullType) PrimType(soot.PrimType) IfStmt(soot.jimple.IfStmt) OdexInstruction(soot.dexpler.instructions.OdexInstruction) DoubleType(soot.DoubleType) EqExpr(soot.jimple.EqExpr) NumericConstant(soot.jimple.NumericConstant) ValueBox(soot.ValueBox) ConditionExpr(soot.jimple.ConditionExpr) Value(soot.Value) SourceLineNumberTag(soot.tagkit.SourceLineNumberTag) Jimple(soot.jimple.Jimple) NullType(soot.NullType) DefinitionStmt(soot.jimple.DefinitionStmt)

Aggregations

EqExpr (soot.jimple.EqExpr)8 NeExpr (soot.jimple.NeExpr)8 Value (soot.Value)6 Local (soot.Local)5 NullType (soot.NullType)5 Type (soot.Type)5 GeExpr (soot.jimple.GeExpr)5 GtExpr (soot.jimple.GtExpr)5 LeExpr (soot.jimple.LeExpr)5 LtExpr (soot.jimple.LtExpr)5 NullConstant (soot.jimple.NullConstant)5 ArrayType (soot.ArrayType)4 Unit (soot.Unit)4 CastExpr (soot.jimple.CastExpr)4 IntType (soot.IntType)3 IntegerType (soot.IntegerType)3 RefType (soot.RefType)3 AddExpr (soot.jimple.AddExpr)3 AndExpr (soot.jimple.AndExpr)3 BinopExpr (soot.jimple.BinopExpr)3