Search in sources :

Example 1 with StringConstant

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

the class MethodCallFinder method inInvokeStmt.

/*
	 * some ASTConstuct{ ASTConstruct{ Some bodies Some Bodies Statement
	 * SequenceNode New Stmt seq node with some stmts some stmts ---------->
	 * Body of method to inline the invoke stmt New Stmt seq node with other
	 * stmts some other stmts Some other bodies Some other bodies End
	 * ASTConstruct End ASTConstruct
	 */
/*
	 * Notice that since this class is only invoked for clinit methods this
	 * invoke statement is some invocation that occured within the clinit method
	 */
public void inInvokeStmt(InvokeStmt s) {
    InvokeExpr invokeExpr = s.getInvokeExpr();
    SootMethod maybeInline = invokeExpr.getMethod();
    // check whether we want to inline
    ASTMethodNode toInlineASTMethod = cleaner.inline(maybeInline);
    if (toInlineASTMethod == null) {
        // not to inline
        return;
    } else {
        // yes we want to inline
        // we know that the method to be inlined has no declarations.
        List<Object> subBodies = toInlineASTMethod.get_SubBodies();
        if (subBodies.size() != 1) {
            throw new RuntimeException("Found ASTMEthod node with more than one subBodies");
        }
        List body = (List) subBodies.get(0);
        ASTParentNodeFinder finder = new ASTParentNodeFinder();
        underAnalysis.apply(finder);
        List<ASTStatementSequenceNode> newChangedBodyPart = createChangedBodyPart(s, body, finder);
        boolean replaced = replaceSubBody(s, newChangedBodyPart, finder);
        if (replaced) {
            // so the invoke stmt has been replaced with the body of the
            // method invoked
            /*
				 * if the inlined method contained an assignment to a static
				 * field we want to replace that with a throw stmt
				 */
            StaticDefinitionFinder defFinder = new StaticDefinitionFinder(maybeInline);
            toInlineASTMethod.apply(defFinder);
            if (defFinder.anyFinalFieldDefined()) {
                // create throw stmt to be added to inlined method
                // create a SootMethodRef
                SootClass runtime = Scene.v().loadClassAndSupport("java.lang.RuntimeException");
                if (runtime.declaresMethod("void <init>(java.lang.String)")) {
                    SootMethod sootMethod = runtime.getMethod("void <init>(java.lang.String)");
                    SootMethodRef methodRef = sootMethod.makeRef();
                    RefType myRefType = RefType.v(runtime);
                    StringConstant tempString = StringConstant.v("This method used to have a definition of a final variable. " + "Dava inlined the definition into the static initializer");
                    List list = new ArrayList();
                    list.add(tempString);
                    GNewInvokeExpr newInvokeExpr = new GNewInvokeExpr(myRefType, methodRef, list);
                    GThrowStmt throwStmt = new GThrowStmt(newInvokeExpr);
                    AugmentedStmt augStmt = new AugmentedStmt(throwStmt);
                    List<AugmentedStmt> sequence = new ArrayList<AugmentedStmt>();
                    sequence.add(augStmt);
                    ASTStatementSequenceNode seqNode = new ASTStatementSequenceNode(sequence);
                    List<Object> subBody = new ArrayList<Object>();
                    subBody.add(seqNode);
                    toInlineASTMethod.replaceBody(subBody);
                }
            }
        }
    }
}
Also used : ASTParentNodeFinder(soot.dava.toolkits.base.AST.traversals.ASTParentNodeFinder) SootMethodRef(soot.SootMethodRef) ArrayList(java.util.ArrayList) ASTStatementSequenceNode(soot.dava.internal.AST.ASTStatementSequenceNode) SootClass(soot.SootClass) AugmentedStmt(soot.dava.internal.asg.AugmentedStmt) RefType(soot.RefType) GNewInvokeExpr(soot.grimp.internal.GNewInvokeExpr) InvokeExpr(soot.jimple.InvokeExpr) GNewInvokeExpr(soot.grimp.internal.GNewInvokeExpr) GThrowStmt(soot.grimp.internal.GThrowStmt) SootMethod(soot.SootMethod) ASTMethodNode(soot.dava.internal.AST.ASTMethodNode) ArrayList(java.util.ArrayList) List(java.util.List) StringConstant(soot.jimple.StringConstant)

Example 2 with StringConstant

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

the class ConstraintCollector method caseAssignStmt.

public void caseAssignStmt(AssignStmt stmt) {
    Value l = stmt.getLeftOp();
    Value r = stmt.getRightOp();
    TypeVariable left = null;
    TypeVariable right = null;
    if (l instanceof ArrayRef) {
        ArrayRef ref = (ArrayRef) l;
        Value base = ref.getBase();
        Value index = ref.getIndex();
        TypeVariable baseType = resolver.typeVariable((Local) base);
        baseType.makeElement();
        left = baseType.element();
        if (index instanceof Local) {
            if (uses) {
                resolver.typeVariable((Local) index).addParent(resolver.typeVariable(IntType.v()));
            }
        }
    } else if (l instanceof Local) {
        left = resolver.typeVariable((Local) l);
    } else if (l instanceof InstanceFieldRef) {
        InstanceFieldRef ref = (InstanceFieldRef) l;
        if (uses) {
            TypeVariable baseType = resolver.typeVariable((Local) ref.getBase());
            baseType.addParent(resolver.typeVariable(ref.getField().getDeclaringClass()));
            left = resolver.typeVariable(ref.getField().getType());
        }
    } else if (l instanceof StaticFieldRef) {
        if (uses) {
            StaticFieldRef ref = (StaticFieldRef) l;
            left = resolver.typeVariable(ref.getField().getType());
        }
    } else {
        throw new RuntimeException("Unhandled assignment left hand side type: " + l.getClass());
    }
    if (r instanceof ArrayRef) {
        ArrayRef ref = (ArrayRef) r;
        Value base = ref.getBase();
        Value index = ref.getIndex();
        TypeVariable baseType = resolver.typeVariable((Local) base);
        baseType.makeElement();
        right = baseType.element();
        if (index instanceof Local) {
            if (uses) {
                resolver.typeVariable((Local) index).addParent(resolver.typeVariable(IntType.v()));
            }
        }
    } else if (r instanceof DoubleConstant) {
        right = resolver.typeVariable(DoubleType.v());
    } else if (r instanceof FloatConstant) {
        right = resolver.typeVariable(FloatType.v());
    } else if (r instanceof IntConstant) {
        right = resolver.typeVariable(IntType.v());
    } else if (r instanceof LongConstant) {
        right = resolver.typeVariable(LongType.v());
    } else if (r instanceof NullConstant) {
        right = resolver.typeVariable(NullType.v());
    } else if (r instanceof StringConstant) {
        right = resolver.typeVariable(RefType.v("java.lang.String"));
    } else if (r instanceof ClassConstant) {
        right = resolver.typeVariable(RefType.v("java.lang.Class"));
    } else if (r instanceof BinopExpr) {
        // ******** BINOP EXPR ********
        BinopExpr be = (BinopExpr) r;
        Value lv = be.getOp1();
        Value rv = be.getOp2();
        TypeVariable lop;
        TypeVariable rop;
        // ******** LEFT ********
        if (lv instanceof Local) {
            lop = resolver.typeVariable((Local) lv);
        } else if (lv instanceof DoubleConstant) {
            lop = resolver.typeVariable(DoubleType.v());
        } else if (lv instanceof FloatConstant) {
            lop = resolver.typeVariable(FloatType.v());
        } else if (lv instanceof IntConstant) {
            lop = resolver.typeVariable(IntType.v());
        } else if (lv instanceof LongConstant) {
            lop = resolver.typeVariable(LongType.v());
        } else if (lv instanceof NullConstant) {
            lop = resolver.typeVariable(NullType.v());
        } else if (lv instanceof StringConstant) {
            lop = resolver.typeVariable(RefType.v("java.lang.String"));
        } else if (lv instanceof ClassConstant) {
            lop = resolver.typeVariable(RefType.v("java.lang.Class"));
        } else {
            throw new RuntimeException("Unhandled binary expression left operand type: " + lv.getClass());
        }
        // ******** RIGHT ********
        if (rv instanceof Local) {
            rop = resolver.typeVariable((Local) rv);
        } else if (rv instanceof DoubleConstant) {
            rop = resolver.typeVariable(DoubleType.v());
        } else if (rv instanceof FloatConstant) {
            rop = resolver.typeVariable(FloatType.v());
        } else if (rv instanceof IntConstant) {
            rop = resolver.typeVariable(IntType.v());
        } else if (rv instanceof LongConstant) {
            rop = resolver.typeVariable(LongType.v());
        } else if (rv instanceof NullConstant) {
            rop = resolver.typeVariable(NullType.v());
        } else if (rv instanceof StringConstant) {
            rop = resolver.typeVariable(RefType.v("java.lang.String"));
        } else if (rv instanceof ClassConstant) {
            rop = resolver.typeVariable(RefType.v("java.lang.Class"));
        } 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) || (be instanceof AndExpr) || (be instanceof OrExpr) || (be instanceof XorExpr)) {
            if (uses) {
                TypeVariable common = resolver.typeVariable();
                rop.addParent(common);
                lop.addParent(common);
            }
            if (left != null) {
                rop.addParent(left);
                lop.addParent(left);
            }
        } else if ((be instanceof ShlExpr) || (be instanceof ShrExpr) || (be instanceof UshrExpr)) {
            if (uses) {
                rop.addParent(resolver.typeVariable(IntType.v()));
            }
            right = lop;
        } else if ((be instanceof CmpExpr) || (be instanceof CmpgExpr) || (be instanceof CmplExpr) || (be instanceof EqExpr) || (be instanceof GeExpr) || (be instanceof GtExpr) || (be instanceof LeExpr) || (be instanceof LtExpr) || (be instanceof NeExpr)) {
            if (uses) {
                TypeVariable common = resolver.typeVariable();
                rop.addParent(common);
                lop.addParent(common);
            }
            right = resolver.typeVariable(IntType.v());
        } else {
            throw new RuntimeException("Unhandled binary expression type: " + be.getClass());
        }
    } else if (r instanceof CastExpr) {
        CastExpr ce = (CastExpr) r;
        right = resolver.typeVariable(ce.getCastType());
    } else if (r instanceof InstanceOfExpr) {
        right = resolver.typeVariable(IntType.v());
    } else if (r instanceof InvokeExpr) {
        InvokeExpr ie = (InvokeExpr) r;
        handleInvokeExpr(ie);
        right = resolver.typeVariable(ie.getMethodRef().returnType());
    } else if (r instanceof NewArrayExpr) {
        NewArrayExpr nae = (NewArrayExpr) r;
        Type baseType = nae.getBaseType();
        if (baseType instanceof ArrayType) {
            right = resolver.typeVariable(ArrayType.v(((ArrayType) baseType).baseType, ((ArrayType) baseType).numDimensions + 1));
        } else {
            right = resolver.typeVariable(ArrayType.v(baseType, 1));
        }
        if (uses) {
            Value size = nae.getSize();
            if (size instanceof Local) {
                TypeVariable var = resolver.typeVariable((Local) size);
                var.addParent(resolver.typeVariable(IntType.v()));
            }
        }
    } else if (r instanceof NewExpr) {
        NewExpr na = (NewExpr) r;
        right = resolver.typeVariable(na.getBaseType());
    } else if (r instanceof NewMultiArrayExpr) {
        NewMultiArrayExpr nmae = (NewMultiArrayExpr) r;
        right = resolver.typeVariable(nmae.getBaseType());
        if (uses) {
            for (int i = 0; i < nmae.getSizeCount(); i++) {
                Value size = nmae.getSize(i);
                if (size instanceof Local) {
                    TypeVariable var = resolver.typeVariable((Local) size);
                    var.addParent(resolver.typeVariable(IntType.v()));
                }
            }
        }
    } else if (r instanceof LengthExpr) {
        LengthExpr le = (LengthExpr) r;
        if (uses) {
            if (le.getOp() instanceof Local) {
                resolver.typeVariable((Local) le.getOp()).makeElement();
            }
        }
        right = resolver.typeVariable(IntType.v());
    } else if (r instanceof NegExpr) {
        NegExpr ne = (NegExpr) r;
        if (ne.getOp() instanceof Local) {
            right = resolver.typeVariable((Local) ne.getOp());
        } else if (ne.getOp() instanceof DoubleConstant) {
            right = resolver.typeVariable(DoubleType.v());
        } else if (ne.getOp() instanceof FloatConstant) {
            right = resolver.typeVariable(FloatType.v());
        } else if (ne.getOp() instanceof IntConstant) {
            right = resolver.typeVariable(IntType.v());
        } else if (ne.getOp() instanceof LongConstant) {
            right = resolver.typeVariable(LongType.v());
        } else {
            throw new RuntimeException("Unhandled neg expression operand type: " + ne.getOp().getClass());
        }
    } else if (r instanceof Local) {
        right = resolver.typeVariable((Local) r);
    } else if (r instanceof InstanceFieldRef) {
        InstanceFieldRef ref = (InstanceFieldRef) r;
        if (uses) {
            TypeVariable baseType = resolver.typeVariable((Local) ref.getBase());
            baseType.addParent(resolver.typeVariable(ref.getField().getDeclaringClass()));
        }
        right = resolver.typeVariable(ref.getField().getType());
    } else if (r instanceof StaticFieldRef) {
        StaticFieldRef ref = (StaticFieldRef) r;
        right = resolver.typeVariable(ref.getField().getType());
    } else {
        throw new RuntimeException("Unhandled assignment right hand side type: " + r.getClass());
    }
    if (left != null && right != null) {
        right.addParent(left);
    }
}
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) InterfaceInvokeExpr(soot.jimple.InterfaceInvokeExpr) DynamicInvokeExpr(soot.jimple.DynamicInvokeExpr) VirtualInvokeExpr(soot.jimple.VirtualInvokeExpr) InvokeExpr(soot.jimple.InvokeExpr) SpecialInvokeExpr(soot.jimple.SpecialInvokeExpr) StaticInvokeExpr(soot.jimple.StaticInvokeExpr) 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) DivExpr(soot.jimple.DivExpr) RefType(soot.RefType) Type(soot.Type) DoubleType(soot.DoubleType) FloatType(soot.FloatType) IntType(soot.IntType) LongType(soot.LongType) NullType(soot.NullType) ArrayType(soot.ArrayType) 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) StringConstant(soot.jimple.StringConstant) CmplExpr(soot.jimple.CmplExpr) ClassConstant(soot.jimple.ClassConstant) BinopExpr(soot.jimple.BinopExpr)

Example 3 with StringConstant

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

the class ConstraintCollector method caseIfStmt.

public void caseIfStmt(IfStmt stmt) {
    if (uses) {
        ConditionExpr cond = (ConditionExpr) stmt.getCondition();
        BinopExpr expr = cond;
        Value lv = expr.getOp1();
        Value rv = expr.getOp2();
        TypeVariable lop;
        TypeVariable rop;
        // ******** LEFT ********
        if (lv instanceof Local) {
            lop = resolver.typeVariable((Local) lv);
        } else if (lv instanceof DoubleConstant) {
            lop = resolver.typeVariable(DoubleType.v());
        } else if (lv instanceof FloatConstant) {
            lop = resolver.typeVariable(FloatType.v());
        } else if (lv instanceof IntConstant) {
            lop = resolver.typeVariable(IntType.v());
        } else if (lv instanceof LongConstant) {
            lop = resolver.typeVariable(LongType.v());
        } else if (lv instanceof NullConstant) {
            lop = resolver.typeVariable(NullType.v());
        } else if (lv instanceof StringConstant) {
            lop = resolver.typeVariable(RefType.v("java.lang.String"));
        } else if (lv instanceof ClassConstant) {
            lop = resolver.typeVariable(RefType.v("java.lang.Class"));
        } else {
            throw new RuntimeException("Unhandled binary expression left operand type: " + lv.getClass());
        }
        // ******** RIGHT ********
        if (rv instanceof Local) {
            rop = resolver.typeVariable((Local) rv);
        } else if (rv instanceof DoubleConstant) {
            rop = resolver.typeVariable(DoubleType.v());
        } else if (rv instanceof FloatConstant) {
            rop = resolver.typeVariable(FloatType.v());
        } else if (rv instanceof IntConstant) {
            rop = resolver.typeVariable(IntType.v());
        } else if (rv instanceof LongConstant) {
            rop = resolver.typeVariable(LongType.v());
        } else if (rv instanceof NullConstant) {
            rop = resolver.typeVariable(NullType.v());
        } else if (rv instanceof StringConstant) {
            rop = resolver.typeVariable(RefType.v("java.lang.String"));
        } else if (rv instanceof ClassConstant) {
            rop = resolver.typeVariable(RefType.v("java.lang.Class"));
        } else {
            throw new RuntimeException("Unhandled binary expression right operand type: " + rv.getClass());
        }
        TypeVariable common = resolver.typeVariable();
        rop.addParent(common);
        lop.addParent(common);
    }
}
Also used : LongConstant(soot.jimple.LongConstant) DoubleConstant(soot.jimple.DoubleConstant) FloatConstant(soot.jimple.FloatConstant) Local(soot.Local) NullConstant(soot.jimple.NullConstant) ConditionExpr(soot.jimple.ConditionExpr) Value(soot.Value) IntConstant(soot.jimple.IntConstant) StringConstant(soot.jimple.StringConstant) ClassConstant(soot.jimple.ClassConstant) BinopExpr(soot.jimple.BinopExpr)

Example 4 with StringConstant

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

the class ConstraintCollector method caseAssignStmt.

public void caseAssignStmt(AssignStmt stmt) {
    Value l = stmt.getLeftOp();
    Value r = stmt.getRightOp();
    TypeVariable left = null;
    TypeVariable 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 (uses) {
                if ((base.numDimensions == 1) && (base.baseType instanceof IntegerType)) {
                    left = resolver.typeVariable(base.baseType);
                }
                if (index instanceof Local) {
                    resolver.typeVariable((Local) index).addParent(resolver.INT);
                }
            }
        }
    } else if (l instanceof Local) {
        if (((Local) l).getType() instanceof IntegerType) {
            left = resolver.typeVariable((Local) l);
        }
    } else if (l instanceof InstanceFieldRef) {
        if (uses) {
            InstanceFieldRef ref = (InstanceFieldRef) l;
            Type fieldType = ref.getFieldRef().type();
            if (fieldType instanceof IntegerType) {
                left = resolver.typeVariable(ref.getFieldRef().type());
            }
        }
    } else if (l instanceof StaticFieldRef) {
        if (uses) {
            StaticFieldRef ref = (StaticFieldRef) l;
            Type fieldType = ref.getFieldRef().type();
            if (fieldType instanceof IntegerType) {
                left = resolver.typeVariable(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)) {
            Value index = ref.getIndex();
            // Be careful, dex can do some weird object/array casting
            if (baset instanceof ArrayType) {
                ArrayType base = (ArrayType) baset;
                if ((base.numDimensions == 1) && (base.baseType instanceof IntegerType)) {
                    right = resolver.typeVariable(base.baseType);
                }
            } else if (baset instanceof IntegerType)
                right = resolver.typeVariable(baset);
            if (uses)
                if (index instanceof Local)
                    resolver.typeVariable((Local) index).addParent(resolver.INT);
        }
    } else if (r instanceof DoubleConstant) {
    } else if (r instanceof FloatConstant) {
    } else if (r instanceof IntConstant) {
        int value = ((IntConstant) r).value;
        if (value < -32768) {
            right = resolver.INT;
        } else if (value < -128) {
            right = resolver.SHORT;
        } else if (value < 0) {
            right = resolver.BYTE;
        } else if (value < 2) {
            right = resolver.R0_1;
        } else if (value < 128) {
            right = resolver.R0_127;
        } else if (value < 32768) {
            right = resolver.R0_32767;
        } else if (value < 65536) {
            right = resolver.CHAR;
        } else {
            right = resolver.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();
        TypeVariable lop = null;
        TypeVariable rop = null;
        // ******** LEFT ********
        if (lv instanceof Local) {
            if (((Local) lv).getType() instanceof IntegerType) {
                lop = resolver.typeVariable((Local) lv);
            }
        } else if (lv instanceof DoubleConstant) {
        } else if (lv instanceof FloatConstant) {
        } else if (lv instanceof IntConstant) {
            int value = ((IntConstant) lv).value;
            if (value < -32768) {
                lop = resolver.INT;
            } else if (value < -128) {
                lop = resolver.SHORT;
            } else if (value < 0) {
                lop = resolver.BYTE;
            } else if (value < 2) {
                lop = resolver.R0_1;
            } else if (value < 128) {
                lop = resolver.R0_127;
            } else if (value < 32768) {
                lop = resolver.R0_32767;
            } else if (value < 65536) {
                lop = resolver.CHAR;
            } else {
                lop = resolver.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 = resolver.typeVariable((Local) rv);
            }
        } else if (rv instanceof DoubleConstant) {
        } else if (rv instanceof FloatConstant) {
        } else if (rv instanceof IntConstant) {
            int value = ((IntConstant) rv).value;
            if (value < -32768) {
                rop = resolver.INT;
            } else if (value < -128) {
                rop = resolver.SHORT;
            } else if (value < 0) {
                rop = resolver.BYTE;
            } else if (value < 2) {
                rop = resolver.R0_1;
            } else if (value < 128) {
                rop = resolver.R0_127;
            } else if (value < 32768) {
                rop = resolver.R0_32767;
            } else if (value < 65536) {
                rop = resolver.CHAR;
            } else {
                rop = resolver.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 DivExpr) || (be instanceof RemExpr) || (be instanceof MulExpr)) {
            if (lop != null && rop != null) {
                if (uses) {
                    if (lop.type() == null) {
                        lop.addParent(resolver.INT);
                    }
                    if (rop.type() == null) {
                        rop.addParent(resolver.INT);
                    }
                }
                right = resolver.INT;
            }
        } else if ((be instanceof AndExpr) || (be instanceof OrExpr) || (be instanceof XorExpr)) {
            if (lop != null && rop != null) {
                TypeVariable common = resolver.typeVariable();
                if (rop != null)
                    rop.addParent(common);
                if (lop != null)
                    lop.addParent(common);
                right = common;
            }
        } else if (be instanceof ShlExpr) {
            if (uses) {
                if (lop != null && lop.type() == null) {
                    lop.addParent(resolver.INT);
                }
                if (rop.type() == null) {
                    rop.addParent(resolver.INT);
                }
            }
            right = (lop == null) ? null : resolver.INT;
        } else if ((be instanceof ShrExpr) || (be instanceof UshrExpr)) {
            if (uses) {
                if (lop != null && lop.type() == null) {
                    lop.addParent(resolver.INT);
                }
                if (rop.type() == null) {
                    rop.addParent(resolver.INT);
                }
            }
            right = lop;
        } else if ((be instanceof CmpExpr) || (be instanceof CmpgExpr) || (be instanceof CmplExpr)) {
            right = resolver.BYTE;
        } else if ((be instanceof EqExpr) || (be instanceof GeExpr) || (be instanceof GtExpr) || (be instanceof LeExpr) || (be instanceof LtExpr) || (be instanceof NeExpr)) {
            if (uses) {
                TypeVariable common = resolver.typeVariable();
                if (rop != null)
                    rop.addParent(common);
                if (lop != null)
                    lop.addParent(common);
            }
            right = resolver.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 = resolver.typeVariable(ce.getCastType());
        }
    } else if (r instanceof InstanceOfExpr) {
        right = resolver.BOOLEAN;
    } else if (r instanceof InvokeExpr) {
        InvokeExpr ie = (InvokeExpr) r;
        handleInvokeExpr(ie);
        if (ie.getMethodRef().returnType() instanceof IntegerType) {
            right = resolver.typeVariable(ie.getMethodRef().returnType());
        }
    } else if (r instanceof NewArrayExpr) {
        NewArrayExpr nae = (NewArrayExpr) r;
        if (uses) {
            Value size = nae.getSize();
            if (size instanceof Local) {
                TypeVariable var = resolver.typeVariable((Local) size);
                var.addParent(resolver.INT);
            }
        }
    } else if (r instanceof NewExpr) {
    } else if (r instanceof NewMultiArrayExpr) {
        NewMultiArrayExpr nmae = (NewMultiArrayExpr) r;
        if (uses) {
            for (int i = 0; i < nmae.getSizeCount(); i++) {
                Value size = nmae.getSize(i);
                if (size instanceof Local) {
                    TypeVariable var = resolver.typeVariable((Local) size);
                    var.addParent(resolver.INT);
                }
            }
        }
    } else if (r instanceof LengthExpr) {
        right = resolver.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) {
                if (uses) {
                    resolver.typeVariable(local).addParent(resolver.INT);
                }
                TypeVariable v = resolver.typeVariable();
                v.addChild(resolver.BYTE);
                v.addChild(resolver.typeVariable(local));
                right = v;
            }
        } else if (ne.getOp() instanceof DoubleConstant) {
        } else if (ne.getOp() instanceof FloatConstant) {
        } else if (ne.getOp() instanceof IntConstant) {
            int value = ((IntConstant) ne.getOp()).value;
            if (value < -32768) {
                right = resolver.INT;
            } else if (value < -128) {
                right = resolver.SHORT;
            } else if (value < 0) {
                right = resolver.BYTE;
            } else if (value < 2) {
                right = resolver.BYTE;
            } else if (value < 128) {
                right = resolver.BYTE;
            } else if (value < 32768) {
                right = resolver.SHORT;
            } else if (value < 65536) {
                right = resolver.INT;
            } else {
                right = resolver.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 = resolver.typeVariable(local);
        }
    } else if (r instanceof InstanceFieldRef) {
        InstanceFieldRef ref = (InstanceFieldRef) r;
        if (ref.getFieldRef().type() instanceof IntegerType) {
            right = resolver.typeVariable(ref.getFieldRef().type());
        }
    } else if (r instanceof StaticFieldRef) {
        StaticFieldRef ref = (StaticFieldRef) r;
        if (ref.getFieldRef().type() instanceof IntegerType) {
            right = resolver.typeVariable(ref.getFieldRef().type());
        }
    } else {
        throw new RuntimeException("Unhandled assignment right hand side type: " + r.getClass());
    }
    if (left != null && right != null && (left.type() == null || right.type() == null)) {
        right.addParent(left);
    }
}
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) Type(soot.Type) 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 5 with StringConstant

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

the class DexNullTransformer method internalTransform.

@Override
protected void internalTransform(final Body body, String phaseName, Map<String, String> options) {
    final DexDefUseAnalysis localDefs = new DexDefUseAnalysis(body);
    AbstractStmtSwitch checkDef = new // Alex: should also end as
    AbstractStmtSwitch() {

        // 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());
                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());
                }
                doBreak = true;
                return;
            } else if (r instanceof StringConstant || r instanceof NewExpr || r instanceof NewArrayExpr) {
                usedAsObject = true;
                doBreak = true;
                return;
            } else if (r instanceof CastExpr) {
                usedAsObject = isObject(((CastExpr) r).getCastType());
                doBreak = true;
                return;
            } else if (r instanceof InvokeExpr) {
                usedAsObject = isObject(((InvokeExpr) r).getType());
                doBreak = true;
                return;
            } else if (r instanceof LengthExpr) {
                usedAsObject = false;
                doBreak = true;
                return;
            // introduces alias
            }
        }

        @Override
        public void caseIdentityStmt(IdentityStmt stmt) {
            if (stmt.getLeftOp() == l) {
                usedAsObject = isObject(stmt.getRightOp().getType());
                doBreak = true;
                return;
            }
        }
    };
    AbstractStmtSwitch checkUse = 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);
            doBreak = true;
            return;
        }

        @Override
        public void caseAssignStmt(AssignStmt stmt) {
            Value left = stmt.getLeftOp();
            Value r = stmt.getRightOp();
            if (left instanceof ArrayRef) {
                ArrayRef ar = (ArrayRef) left;
                if (ar.getIndex() == l) {
                    doBreak = true;
                    return;
                } else if (ar.getBase() == l) {
                    usedAsObject = true;
                    doBreak = true;
                    return;
                }
            }
            if (left instanceof InstanceFieldRef) {
                InstanceFieldRef ifr = (InstanceFieldRef) left;
                if (ifr.getBase() == l) {
                    usedAsObject = true;
                    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;
                    doBreak = true;
                    return;
                } else if (l instanceof InstanceFieldRef && isObject(((InstanceFieldRef) l).getFieldRef().type())) {
                    usedAsObject = true;
                    doBreak = true;
                    return;
                } else if (l instanceof ArrayRef) {
                    Type aType = ((ArrayRef) l).getType();
                    if (aType instanceof UnknownType) {
                        usedAsObject = stmt.hasTag(// isObject(
                        "ObjectOpTag");
                    // findArrayType(g,
                    // localDefs,
                    // localUses,
                    // stmt));
                    } else {
                        usedAsObject = isObject(aType);
                    }
                    doBreak = true;
                    return;
                }
            }
            // is used as value (does not exclude assignment)
            if (r instanceof FieldRef) {
                // isObject(((FieldRef)
                usedAsObject = true;
                // r).getFieldRef().type());
                doBreak = true;
                return;
            } else if (r instanceof ArrayRef) {
                ArrayRef ar = (ArrayRef) r;
                if (ar.getBase() == l) {
                    usedAsObject = true;
                } else {
                    // used as index
                    usedAsObject = false;
                }
                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;
                doBreak = true;
                return;
            } else if (r instanceof CastExpr) {
                usedAsObject = isObject(((CastExpr) r).getCastType());
                doBreak = true;
                return;
            } else if (r instanceof InvokeExpr) {
                usedAsObject = examineInvokeExpr((InvokeExpr) stmt.getRightOp());
                doBreak = true;
                return;
            } else if (r instanceof LengthExpr) {
                usedAsObject = true;
                doBreak = true;
                return;
            } else if (r instanceof BinopExpr) {
                usedAsObject = false;
                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;
            doBreak = true;
            return;
        }

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

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

        @Override
        public void caseThrowStmt(ThrowStmt stmt) {
            usedAsObject = stmt.getOp() == l;
            doBreak = true;
            return;
        }
    };
    for (Local loc : getNullCandidates(body)) {
        usedAsObject = false;
        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 if (u instanceof IfStmt) {
                throw new RuntimeException("ERROR: def can not be something else than Assign or Identity statement! (def: " + u + " class: " + u.getClass() + "");
            }
            // check defs
            u.apply(checkDef);
            if (doBreak)
                break;
            // check uses
            for (Unit use : localDefs.getUsesOf(l)) {
                use.apply(checkUse);
                if (doBreak)
                    break;
            }
            // for uses
            if (doBreak)
                break;
        }
        // change values
        if (usedAsObject) {
            for (Unit u : defs) {
                replaceWithNull(u);
                Set<Value> defLocals = new HashSet<Value>();
                for (ValueBox vb : u.getDefBoxes()) defLocals.add(vb.getValue());
                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() || !defLocals.contains(use.getArrayRef().getBase()))
                        replaceWithNull(use);
                }
            }
        }
    // end if
    }
    // Check for inlined zero values
    AbstractStmtSwitch inlinedZeroValues = new AbstractStmtSwitch() {

        final NullConstant nullConstant = NullConstant.v();

        @Override
        public void caseAssignStmt(AssignStmt stmt) {
            // Case a = 0 with a being an object
            if (isObject(stmt.getLeftOp().getType()) && isConstZero(stmt.getRightOp())) {
                stmt.setRightOp(nullConstant);
                return;
            }
            // Case a = (Object) 0
            if (stmt.getRightOp() instanceof CastExpr) {
                CastExpr ce = (CastExpr) stmt.getRightOp();
                if (isObject(ce.getCastType()) && isConstZero(ce.getOp())) {
                    stmt.setRightOp(nullConstant);
                }
            }
            // Case a[0] = 0
            if (stmt.getLeftOp() instanceof ArrayRef && isConstZero(stmt.getRightOp())) {
                ArrayRef ar = (ArrayRef) stmt.getLeftOp();
                if (isObjectArray(ar.getBase(), body) || stmt.hasTag("ObjectOpTag")) {
                    stmt.setRightOp(nullConstant);
                }
            }
        }

        private boolean isConstZero(Value rightOp) {
            if (rightOp instanceof IntConstant && ((IntConstant) rightOp).value == 0)
                return true;
            if (rightOp instanceof LongConstant && ((LongConstant) rightOp).value == 0)
                return true;
            return false;
        }

        @Override
        public void caseReturnStmt(ReturnStmt stmt) {
            if (stmt.getOp() instanceof IntConstant && isObject(body.getMethod().getReturnType())) {
                IntConstant iconst = (IntConstant) stmt.getOp();
                assert iconst.value == 0;
                stmt.setOp(nullConstant);
            }
        }

        @Override
        public void caseEnterMonitorStmt(EnterMonitorStmt stmt) {
            if (stmt.getOp() instanceof IntConstant && ((IntConstant) stmt.getOp()).value == 0)
                stmt.setOp(nullConstant);
        }

        @Override
        public void caseExitMonitorStmt(ExitMonitorStmt stmt) {
            if (stmt.getOp() instanceof IntConstant && ((IntConstant) stmt.getOp()).value == 0)
                stmt.setOp(nullConstant);
        }
    };
    final NullConstant nullConstant = NullConstant.v();
    for (Unit u : body.getUnits()) {
        u.apply(inlinedZeroValues);
        if (u instanceof Stmt) {
            Stmt stmt = (Stmt) u;
            if (stmt.containsInvokeExpr()) {
                InvokeExpr invExpr = stmt.getInvokeExpr();
                for (int i = 0; i < invExpr.getArgCount(); i++) if (isObject(invExpr.getMethodRef().parameterType(i)))
                    if (invExpr.getArg(i) instanceof IntConstant) {
                        IntConstant iconst = (IntConstant) invExpr.getArg(i);
                        assert iconst.value == 0;
                        invExpr.setArg(i, nullConstant);
                    }
            }
        }
    }
}
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) AbstractStmtSwitch(soot.jimple.AbstractStmtSwitch) CastExpr(soot.jimple.CastExpr) InstanceFieldRef(soot.jimple.InstanceFieldRef) IntConstant(soot.jimple.IntConstant) IdentityStmt(soot.jimple.IdentityStmt) EnterMonitorStmt(soot.jimple.EnterMonitorStmt) HashSet(java.util.HashSet) LongConstant(soot.jimple.LongConstant) FieldRef(soot.jimple.FieldRef) InstanceFieldRef(soot.jimple.InstanceFieldRef) StaticFieldRef(soot.jimple.StaticFieldRef) SootMethodRef(soot.SootMethodRef) LengthExpr(soot.jimple.LengthExpr) Local(soot.Local) NullConstant(soot.jimple.NullConstant) StaticFieldRef(soot.jimple.StaticFieldRef) UnknownType(soot.UnknownType) UnknownType(soot.UnknownType) ArrayType(soot.ArrayType) Type(soot.Type) IfStmt(soot.jimple.IfStmt) NewArrayExpr(soot.jimple.NewArrayExpr) ValueBox(soot.ValueBox) Value(soot.Value) NewExpr(soot.jimple.NewExpr) StringConstant(soot.jimple.StringConstant) ReturnStmt(soot.jimple.ReturnStmt) ThrowStmt(soot.jimple.ThrowStmt) DefinitionStmt(soot.jimple.DefinitionStmt) BinopExpr(soot.jimple.BinopExpr)

Aggregations

StringConstant (soot.jimple.StringConstant)16 Local (soot.Local)10 Value (soot.Value)10 IntConstant (soot.jimple.IntConstant)10 LongConstant (soot.jimple.LongConstant)10 NullConstant (soot.jimple.NullConstant)10 ClassConstant (soot.jimple.ClassConstant)9 DoubleConstant (soot.jimple.DoubleConstant)9 FloatConstant (soot.jimple.FloatConstant)9 BinopExpr (soot.jimple.BinopExpr)8 InvokeExpr (soot.jimple.InvokeExpr)7 Type (soot.Type)6 NewArrayExpr (soot.jimple.NewArrayExpr)6 NewExpr (soot.jimple.NewExpr)6 ArrayType (soot.ArrayType)5 SootMethodRef (soot.SootMethodRef)5 ArrayRef (soot.jimple.ArrayRef)5 CastExpr (soot.jimple.CastExpr)5 InstanceFieldRef (soot.jimple.InstanceFieldRef)5 LengthExpr (soot.jimple.LengthExpr)5