Search in sources :

Example 6 with LongType

use of soot.LongType in project soot by Sable.

the class DalvikTyper method assignType.

@Override
public void assignType(final Body b) {
    // Debug.printDbg("assignTypes: before: \n", b);
    constraints.clear();
    localObjList.clear();
    final Set<Unit> todoUnits = new HashSet<Unit>();
    // put constraints:
    for (Unit u : b.getUnits()) {
        StmtSwitch ss = new StmtSwitch() {

            @Override
            public void caseBreakpointStmt(BreakpointStmt stmt) {
            // nothing
            }

            @Override
            public void caseInvokeStmt(InvokeStmt stmt) {
                // add constraint
                DalvikTyper.v().setInvokeType(stmt.getInvokeExpr());
            }

            @Override
            public void caseAssignStmt(AssignStmt stmt) {
                // add constraint
                Value l = stmt.getLeftOp();
                Value r = stmt.getRightOp();
                // size in new array expression is of tye integer
                if (r instanceof NewArrayExpr) {
                    NewArrayExpr nae = (NewArrayExpr) r;
                    ValueBox sb = nae.getSizeBox();
                    if (sb.getValue() instanceof Local) {
                        DalvikTyper.v().setType(sb, IntType.v(), true);
                    }
                }
                // array index is of type integer
                if (stmt.containsArrayRef()) {
                    ArrayRef ar = stmt.getArrayRef();
                    ValueBox sb = ar.getIndexBox();
                    if (sb.getValue() instanceof Local) {
                        DalvikTyper.v().setType(sb, IntType.v(), true);
                    }
                }
                if (l instanceof Local && r instanceof Local) {
                    DalvikTyper.v().addConstraint(stmt.getLeftOpBox(), stmt.getRightOpBox());
                    return;
                }
                if (stmt.containsInvokeExpr()) {
                    DalvikTyper.v().setInvokeType(stmt.getInvokeExpr());
                }
                if (r instanceof Local) {
                    // l NOT local
                    Type leftType = stmt.getLeftOp().getType();
                    if (l instanceof ArrayRef && leftType instanceof UnknownType) {
                        // find type later
                        todoUnits.add(stmt);
                        return;
                    }
                    DalvikTyper.v().setType(stmt.getRightOpBox(), leftType, true);
                    return;
                }
                if (l instanceof Local) {
                    if (r instanceof UntypedConstant)
                        return;
                    for (Tag t : stmt.getTags()) {
                        if (r instanceof CastExpr) {
                            // do not check tag, since the tag is for the operand of the cast
                            break;
                        }
                        // Debug.printDbg("assign stmt tag: ", stmt, t);
                        if (t instanceof IntOpTag) {
                            checkExpr(r, IntType.v());
                            DalvikTyper.v().setType(stmt.getLeftOpBox(), IntType.v(), false);
                            return;
                        } else if (t instanceof FloatOpTag) {
                            checkExpr(r, FloatType.v());
                            DalvikTyper.v().setType(stmt.getLeftOpBox(), FloatType.v(), false);
                            return;
                        } else if (t instanceof DoubleOpTag) {
                            checkExpr(r, DoubleType.v());
                            DalvikTyper.v().setType(stmt.getLeftOpBox(), DoubleType.v(), false);
                            return;
                        } else if (t instanceof LongOpTag) {
                            checkExpr(r, LongType.v());
                            DalvikTyper.v().setType(stmt.getLeftOpBox(), LongType.v(), false);
                            return;
                        }
                    }
                    Type rightType = stmt.getRightOp().getType();
                    if (r instanceof ArrayRef && rightType instanceof UnknownType) {
                        // find type later
                        todoUnits.add(stmt);
                        return;
                    } else if (r instanceof CastExpr) {
                        CastExpr ce = (CastExpr) r;
                        Type castType = ce.getCastType();
                        if (castType instanceof PrimType) {
                            // check incoming primitive type
                            for (Tag t : stmt.getTags()) {
                                // Debug.printDbg("assign primitive type from stmt tag: ", stmt, t);
                                if (t instanceof IntOpTag) {
                                    DalvikTyper.v().setType(ce.getOpBox(), IntType.v(), false);
                                    return;
                                } else if (t instanceof FloatOpTag) {
                                    DalvikTyper.v().setType(ce.getOpBox(), FloatType.v(), false);
                                    return;
                                } else if (t instanceof DoubleOpTag) {
                                    DalvikTyper.v().setType(ce.getOpBox(), DoubleType.v(), false);
                                    return;
                                } else if (t instanceof LongOpTag) {
                                    DalvikTyper.v().setType(ce.getOpBox(), LongType.v(), false);
                                    return;
                                }
                            }
                        } else {
                            // incoming type is object
                            DalvikTyper.v().setType(ce.getOpBox(), RefType.v("java.lang.Object"), false);
                        }
                    }
                    DalvikTyper.v().setType(stmt.getLeftOpBox(), rightType, false);
                    return;
                }
            }

            @Override
            public void caseIdentityStmt(IdentityStmt stmt) {
                DalvikTyper.v().setType(stmt.getLeftOpBox(), stmt.getRightOp().getType(), false);
            }

            @Override
            public void caseEnterMonitorStmt(EnterMonitorStmt stmt) {
                // add constraint
                DalvikTyper.v().setType(stmt.getOpBox(), RefType.v("java.lang.Object"), true);
            }

            @Override
            public void caseExitMonitorStmt(ExitMonitorStmt stmt) {
                // add constraint
                DalvikTyper.v().setType(stmt.getOpBox(), RefType.v("java.lang.Object"), true);
            }

            @Override
            public void caseGotoStmt(GotoStmt stmt) {
            // nothing
            }

            @Override
            public void caseIfStmt(IfStmt stmt) {
                // add constraint
                Value c = stmt.getCondition();
                if (c instanceof BinopExpr) {
                    BinopExpr bo = (BinopExpr) c;
                    Value op1 = bo.getOp1();
                    Value op2 = bo.getOp2();
                    if (op1 instanceof Local && op2 instanceof Local) {
                        DalvikTyper.v().addConstraint(bo.getOp1Box(), bo.getOp2Box());
                    }
                }
            }

            @Override
            public void caseLookupSwitchStmt(LookupSwitchStmt stmt) {
                // add constraint
                DalvikTyper.v().setType(stmt.getKeyBox(), IntType.v(), true);
            }

            @Override
            public void caseNopStmt(NopStmt stmt) {
            // nothing
            }

            @Override
            public void caseRetStmt(RetStmt stmt) {
            // nothing
            }

            @Override
            public void caseReturnStmt(ReturnStmt stmt) {
                // add constraint
                DalvikTyper.v().setType(stmt.getOpBox(), b.getMethod().getReturnType(), true);
            }

            @Override
            public void caseReturnVoidStmt(ReturnVoidStmt stmt) {
            // nothing
            }

            @Override
            public void caseTableSwitchStmt(TableSwitchStmt stmt) {
                // add constraint
                DalvikTyper.v().setType(stmt.getKeyBox(), IntType.v(), true);
            }

            @Override
            public void caseThrowStmt(ThrowStmt stmt) {
                // add constraint
                DalvikTyper.v().setType(stmt.getOpBox(), RefType.v("java.lang.Object"), true);
            }

            @Override
            public void defaultCase(Object obj) {
                throw new RuntimeException("error: unknown statement: " + obj);
            }
        };
        u.apply(ss);
    }
    // <com.admob.android.ads.q: void a(android.os.Bundle,java.lang.String,java.lang.Object)>
    if (!todoUnits.isEmpty()) {
        // propagate array types
        UnitGraph ug = new ExceptionalUnitGraph(b);
        SimpleLocalDefs sld = new SimpleLocalDefs(ug);
        SimpleLocalUses slu = new SimpleLocalUses(b, sld);
        for (Unit u : b.getUnits()) {
            if (u instanceof DefinitionStmt) {
                // Debug.printDbg("U: ", u);
                DefinitionStmt ass = (DefinitionStmt) u;
                Value r = ass.getRightOp();
                if (r instanceof UntypedConstant)
                    continue;
                Type rType = r.getType();
                if (rType instanceof ArrayType && ass.getLeftOp() instanceof Local) {
                    // Debug.printDbg("propagate-array: checking ", u);
                    // propagate array type through aliases
                    Set<Unit> done = new HashSet<Unit>();
                    Set<DefinitionStmt> toDo = new HashSet<DefinitionStmt>();
                    toDo.add(ass);
                    while (!toDo.isEmpty()) {
                        DefinitionStmt currentUnit = toDo.iterator().next();
                        if (done.contains(currentUnit)) {
                            toDo.remove(currentUnit);
                            continue;
                        }
                        done.add(currentUnit);
                        for (UnitValueBoxPair uvbp : slu.getUsesOf(currentUnit)) {
                            Unit use = uvbp.unit;
                            Value l2 = null;
                            Value r2 = null;
                            if (use instanceof AssignStmt) {
                                AssignStmt ass2 = (AssignStmt) use;
                                l2 = ass2.getLeftOp();
                                r2 = ass2.getRightOp();
                                if (!(l2 instanceof Local) || !(r2 instanceof Local || r2 instanceof ArrayRef)) {
                                    // Debug.printDbg("propagate-array: skipping ", use);
                                    continue;
                                }
                                Type newType = null;
                                if (r2 instanceof Local) {
                                    List<LocalObj> lobjs = local2Obj.get(r2);
                                    newType = lobjs.get(0).t;
                                } else if (r2 instanceof ArrayRef) {
                                    ArrayRef ar = (ArrayRef) r2;
                                    // skip if use is in index
                                    if (ar.getIndex() == currentUnit.getLeftOp()) {
                                        // Debug.printDbg("skipping since local is used as index...");
                                        continue;
                                    }
                                    Local arBase = (Local) ar.getBase();
                                    List<LocalObj> lobjs = local2Obj.get(arBase);
                                    Type baseT = lobjs.get(0).t;
                                    if (baseT.toString().equals(("java.lang.Object"))) {
                                        // look for an array type, because an TTT[] is also an Object...
                                        ArrayType aTypeOtherThanObject = null;
                                        for (LocalObj lo : local2Obj.get(arBase)) {
                                            if (lo.t instanceof ArrayType) {
                                                aTypeOtherThanObject = (ArrayType) lo.t;
                                            }
                                        }
                                        if (aTypeOtherThanObject == null) {
                                            throw new RuntimeException("error: did not found array type for base " + arBase + " " + local2Obj.get(arBase) + " \n " + b);
                                        }
                                        baseT = aTypeOtherThanObject;
                                    }
                                    ArrayType at = (ArrayType) baseT;
                                    newType = at.getElementType();
                                } else {
                                    throw new RuntimeException("error: expected Local or ArrayRef. Got " + r2);
                                }
                                toDo.add((DefinitionStmt) use);
                                DalvikTyper.v().setType(ass2.getLeftOpBox(), newType, true);
                            }
                        }
                    }
                }
            }
        }
        for (Unit u : todoUnits) {
        // Debug.printDbg("todo unit: ", u);
        }
        while (!todoUnits.isEmpty()) {
            Unit u = todoUnits.iterator().next();
            if (!(u instanceof AssignStmt)) {
                throw new RuntimeException("error: expecting assign stmt. Got " + u);
            }
            AssignStmt ass = (AssignStmt) u;
            Value l = ass.getLeftOp();
            Value r = ass.getRightOp();
            ArrayRef ar = null;
            Local loc = null;
            if (l instanceof ArrayRef) {
                ar = (ArrayRef) l;
                loc = (Local) r;
            } else if (r instanceof ArrayRef) {
                ar = (ArrayRef) r;
                loc = (Local) l;
            } else {
                throw new RuntimeException("error: expecting an array ref. Got " + u);
            }
            Local baselocal = (Local) ar.getBase();
            if (!local2Obj.containsKey(baselocal)) {
                // Debug.printDbg("b: ", b.getMethod(), " \n", b);
                throw new RuntimeException("oups");
            }
            Type baseT = local2Obj.get(baselocal).get(0).t;
            if (baseT.toString().equals(("java.lang.Object"))) {
                // look for an array type, because an TTT[] is also an Object...
                ArrayType aTypeOtherThanObject = null;
                for (LocalObj lo : local2Obj.get(baselocal)) {
                    if (lo.t instanceof ArrayType) {
                        aTypeOtherThanObject = (ArrayType) lo.t;
                    }
                }
                if (aTypeOtherThanObject == null) {
                    throw new RuntimeException("did not found array type for base " + baselocal + " " + local2Obj.get(baselocal) + " \n " + b);
                }
                baseT = aTypeOtherThanObject;
            }
            ArrayType basetype = (ArrayType) baseT;
            // Debug.printDbg("v: ", ar, " base:", ar.getBase(), " base type: ", basetype, " type: ", ar.getType());
            Type t = basetype.getElementType();
            if (t instanceof UnknownType) {
                todoUnits.add(u);
                continue;
            } else {
                DalvikTyper.v().setType(ar == l ? ass.getRightOpBox() : ass.getLeftOpBox(), t, true);
                todoUnits.remove(u);
            }
        }
    // throw new RuntimeException("ouppppp");
    }
    // Debug.printDbg(IDalvikTyper.DEBUG, "list of constraints:");
    List<ValueBox> vbList = b.getUseAndDefBoxes();
    // clear constraints after local splitting and dead code eliminator
    List<Constraint> toRemove = new ArrayList<Constraint>();
    for (Constraint c : constraints) {
        if (!vbList.contains(c.l)) {
            // Debug.printDbg(IDalvikTyper.DEBUG, "warning: ", c.l, " not in locals! removing...");
            toRemove.add(c);
            continue;
        }
        if (!vbList.contains(c.r)) {
            // Debug.printDbg(IDalvikTyper.DEBUG, "warning: ", c.r, " not in locals! removing...");
            toRemove.add(c);
            continue;
        }
    }
    for (Constraint c : toRemove) constraints.remove(c);
    // keep only valid locals
    for (LocalObj lo : localObjList) {
        if (!vbList.contains(lo.vb)) {
            // Debug.printDbg(IDalvikTyper.DEBUG, "  -- removing vb: ", lo.vb, " with type ", lo.t);
            continue;
        }
        Local l = lo.getLocal();
        Type t = lo.t;
        if (localTemp.contains(l) && lo.isUse) {
        // Debug.printDbg(IDalvikTyper.DEBUG, "  /!\\ def already added for local ", l, "! for vb: ", lo.vb);
        } else {
            // Debug.printDbg(IDalvikTyper.DEBUG, "  * add type ", t, " to local ", l, " for vb: ", lo.vb);
            localTemp.add(l);
            typed.put(lo.vb, t);
        }
    }
    for (ValueBox vb : typed.keySet()) {
        if (vb.getValue() instanceof Local) {
            Local l = (Local) vb.getValue();
            localTyped.put(l, typed.get(vb));
        }
    }
    for (Constraint c : constraints) // Debug.printDbg(IDalvikTyper.DEBUG, "  -> constraint: ", c);
    for (ValueBox vb : typed.keySet()) {
    // Debug.printDbg(IDalvikTyper.DEBUG, "    typed: ", vb, " -> ", typed.get(vb));
    }
    for (Local l : localTyped.keySet()) {
    // Debug.printDbg(IDalvikTyper.DEBUG, "    localTyped: ", l, " -> ", localTyped.get(l));
    }
    while (!constraints.isEmpty()) {
        boolean update = false;
        for (Constraint c : constraints) {
            // Debug.printDbg(IDalvikTyper.DEBUG, "current constraint: ", c);
            Value l = c.l.getValue();
            Value r = c.r.getValue();
            if (l instanceof Local && r instanceof Constant) {
                Constant cst = (Constant) r;
                if (!localTyped.containsKey(l))
                    continue;
                Type lt = localTyped.get(l);
                // Debug.printDbg(IDalvikTyper.DEBUG, "would like to set type ", lt, " to constant: ", c);
                Value newValue = null;
                if (lt instanceof IntType || lt instanceof BooleanType || lt instanceof ShortType || lt instanceof CharType || lt instanceof ByteType) {
                    UntypedIntOrFloatConstant uf = (UntypedIntOrFloatConstant) cst;
                    newValue = uf.toIntConstant();
                } else if (lt instanceof FloatType) {
                    UntypedIntOrFloatConstant uf = (UntypedIntOrFloatConstant) cst;
                    newValue = uf.toFloatConstant();
                } else if (lt instanceof DoubleType) {
                    UntypedLongOrDoubleConstant ud = (UntypedLongOrDoubleConstant) cst;
                    newValue = ud.toDoubleConstant();
                } else if (lt instanceof LongType) {
                    UntypedLongOrDoubleConstant ud = (UntypedLongOrDoubleConstant) cst;
                    newValue = ud.toLongConstant();
                } else {
                    if (cst instanceof UntypedIntOrFloatConstant && ((UntypedIntOrFloatConstant) cst).value == 0) {
                        newValue = NullConstant.v();
                    // Debug.printDbg("new null constant for constraint ", c, " with l type: ", localTyped.get(l));
                    } else {
                        throw new RuntimeException("unknow type for constance: " + lt);
                    }
                }
                c.r.setValue(newValue);
                // Debug.printDbg(IDalvikTyper.DEBUG, "remove constraint: ", c);
                constraints.remove(c);
                update = true;
                break;
            } else if (l instanceof Local && r instanceof Local) {
                Local leftLocal = (Local) l;
                Local rightLocal = (Local) r;
                if (localTyped.containsKey(leftLocal)) {
                    Type leftLocalType = localTyped.get(leftLocal);
                    if (!localTyped.containsKey(rightLocal)) {
                        // Debug.printDbg(IDalvikTyper.DEBUG, "set type ", leftLocalType, " to local ", rightLocal);
                        rightLocal.setType(leftLocalType);
                        setLocalTyped(rightLocal, leftLocalType);
                    }
                    // Debug.printDbg(IDalvikTyper.DEBUG, "remove constraint: ", c);
                    constraints.remove(c);
                    update = true;
                    break;
                } else if (localTyped.containsKey(rightLocal)) {
                    Type rightLocalType = localTyped.get(rightLocal);
                    if (!localTyped.containsKey(leftLocal)) {
                        // Debug.printDbg(IDalvikTyper.DEBUG, "set type ", rightLocalType, " to local ", leftLocal);
                        leftLocal.setType(rightLocalType);
                        setLocalTyped(leftLocal, rightLocalType);
                    }
                    // Debug.printDbg(IDalvikTyper.DEBUG, "remove constraint: ", c);
                    constraints.remove(c);
                    update = true;
                    break;
                }
            } else if (l instanceof ArrayRef && r instanceof Local) {
                Local rightLocal = (Local) r;
                ArrayRef ar = (ArrayRef) l;
                Local base = (Local) ar.getBase();
                // Debug.printDbg(IDalvikTyper.DEBUG, "index: ", ar.getIndex());
                if (localTyped.containsKey(base)) {
                    Type t = localTyped.get(base);
                    // Debug.printDbg(IDalvikTyper.DEBUG, "type of local1: ", t, " ", t.getClass());
                    Type elementType = null;
                    if (t instanceof ArrayType) {
                        ArrayType at = (ArrayType) t;
                        elementType = at.getArrayElementType();
                    } else {
                        continue;
                    }
                    if (!localTyped.containsKey(rightLocal)) {
                        // Debug.printDbg(IDalvikTyper.DEBUG, "set type ", elementType, " to local ", r);
                        rightLocal.setType(elementType);
                        setLocalTyped(rightLocal, elementType);
                    }
                    // Debug.printDbg(IDalvikTyper.DEBUG, "remove constraint: ", c);
                    constraints.remove(c);
                    update = true;
                    break;
                }
            } else if (l instanceof Local && r instanceof ArrayRef) {
                Local leftLocal = (Local) l;
                ArrayRef ar = (ArrayRef) r;
                Local base = (Local) ar.getBase();
                if (localTyped.containsKey(base)) {
                    Type t = localTyped.get(base);
                    // Debug.printDbg(IDalvikTyper.DEBUG, "type of local2: ", t, " ", t.getClass());
                    Type elementType = null;
                    if (t instanceof ArrayType) {
                        ArrayType at = (ArrayType) t;
                        elementType = at.getArrayElementType();
                    } else {
                        continue;
                    }
                    if (!localTyped.containsKey(leftLocal)) {
                        // Debug.printDbg(IDalvikTyper.DEBUG, "set type ", elementType, " to local ", l);
                        leftLocal.setType(elementType);
                        setLocalTyped(leftLocal, elementType);
                    }
                    // Debug.printDbg(IDalvikTyper.DEBUG, "remove constraint: ", c);
                    constraints.remove(c);
                    update = true;
                    break;
                }
            } else {
                throw new RuntimeException("error: do not handling this kind of constraint: " + c);
            }
        }
        if (!update)
            break;
    }
    for (Unit u : b.getUnits()) {
        if (!(u instanceof AssignStmt))
            continue;
        AssignStmt ass = (AssignStmt) u;
        if (!(ass.getLeftOp() instanceof Local))
            continue;
        if (!(ass.getRightOp() instanceof UntypedConstant))
            continue;
        UntypedConstant uc = (UntypedConstant) ass.getRightOp();
        ass.setRightOp(uc.defineType(localTyped.get(ass.getLeftOp())));
    }
    // 
    for (Constraint c : constraints) {
        // Debug.printDbg(IDalvikTyper.DEBUG, "current constraint: ", c);
        Value l = c.l.getValue();
        Value r = c.r.getValue();
        if (l instanceof Local && r instanceof Constant) {
            if (r instanceof UntypedIntOrFloatConstant) {
                UntypedIntOrFloatConstant cst = (UntypedIntOrFloatConstant) r;
                Value newValue = null;
                if (cst.value != 0) {
                    // Debug.printDbg(IDalvikTyper.DEBUG, "[untyped constaints] set type int to non zero constant: ", c, " = ", cst.value);
                    newValue = cst.toIntConstant();
                } else {
                    // check if used in cast, just in case...
                    for (Unit u : b.getUnits()) {
                        for (ValueBox vb1 : u.getUseBoxes()) {
                            Value v1 = vb1.getValue();
                            if (v1 == l) {
                                // Debug.printDbg("local used in ", u);
                                if (u instanceof AssignStmt) {
                                    AssignStmt a = (AssignStmt) u;
                                    Value right = a.getRightOp();
                                    if (right instanceof CastExpr) {
                                        newValue = NullConstant.v();
                                    } else {
                                        newValue = cst.toIntConstant();
                                    }
                                } else if (u instanceof IfStmt) {
                                    // TODO check this better
                                    newValue = cst.toIntConstant();
                                }
                            }
                        }
                    }
                }
                if (newValue == null) {
                    throw new RuntimeException("error: no type found for local: " + l);
                }
                c.r.setValue(newValue);
            } else if (r instanceof UntypedLongOrDoubleConstant) {
                // Debug.printDbg(IDalvikTyper.DEBUG, "[untyped constaints] set type long to constant: ", c);
                Value newValue = ((UntypedLongOrDoubleConstant) r).toLongConstant();
                c.r.setValue(newValue);
            }
        }
    }
    // fix untypedconstants which have flown to an array index
    for (Unit u : b.getUnits()) {
        StmtSwitch sw = new StmtSwitch() {

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

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

            @Override
            public void caseAssignStmt(AssignStmt stmt) {
                if (stmt.getRightOp() instanceof NewArrayExpr) {
                    NewArrayExpr nae = (NewArrayExpr) stmt.getRightOp();
                    if (nae.getSize() instanceof UntypedConstant) {
                        UntypedIntOrFloatConstant uc = (UntypedIntOrFloatConstant) nae.getSize();
                        nae.setSize(uc.defineType(IntType.v()));
                    }
                } else if (stmt.getRightOp() instanceof UntypedConstant) {
                    UntypedConstant uc = (UntypedConstant) stmt.getRightOp();
                    Value l = stmt.getLeftOp();
                    Type lType = null;
                    if (l instanceof ArrayRef) {
                        ArrayRef ar = (ArrayRef) l;
                        Local baseLocal = (Local) ar.getBase();
                        ArrayType arrayType = (ArrayType) localTyped.get(baseLocal);
                        lType = arrayType.getElementType();
                    } else {
                        lType = l.getType();
                    }
                    stmt.setRightOp(uc.defineType(lType));
                } else if (stmt.getRightOp() instanceof InvokeExpr) {
                    changeUntypedConstantsInInvoke((InvokeExpr) stmt.getRightOp());
                }
                if (!stmt.containsArrayRef()) {
                    return;
                }
                ArrayRef ar = stmt.getArrayRef();
                if ((ar.getIndex() instanceof UntypedConstant)) {
                    UntypedIntOrFloatConstant uc = (UntypedIntOrFloatConstant) ar.getIndex();
                    ar.setIndex(uc.toIntConstant());
                }
                if (stmt.getLeftOp() instanceof ArrayRef && stmt.getRightOp() instanceof UntypedConstant) {
                    UntypedConstant uc = (UntypedConstant) stmt.getRightOp();
                    Local baseLocal = (Local) stmt.getArrayRef().getBase();
                    ArrayType lType = (ArrayType) localTyped.get(baseLocal);
                    Type elemType = lType.getElementType();
                    stmt.setRightOp(uc.defineType(elemType));
                }
            }

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

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

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

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

            @Override
            public void caseIfStmt(IfStmt stmt) {
                Value c = stmt.getCondition();
                if (c instanceof BinopExpr) {
                    BinopExpr be = (BinopExpr) c;
                    Value op1 = be.getOp1();
                    Value op2 = be.getOp2();
                    if (op1 instanceof UntypedConstant || op2 instanceof UntypedConstant) {
                        if (op1 instanceof Local) {
                            Type t = localTyped.get(op1);
                            // Debug.printDbg("if op1 type: ", t);
                            UntypedConstant uc = (UntypedConstant) op2;
                            be.setOp2(uc.defineType(t));
                        } else if (op2 instanceof Local) {
                            Type t = localTyped.get(op2);
                            // Debug.printDbg("if op2 type: ", t);
                            UntypedConstant uc = (UntypedConstant) op1;
                            be.setOp1(uc.defineType(t));
                        } else if (op1 instanceof UntypedConstant && op2 instanceof UntypedConstant) {
                            if (op1 instanceof UntypedIntOrFloatConstant && op2 instanceof UntypedIntOrFloatConstant) {
                                UntypedIntOrFloatConstant uc1 = (UntypedIntOrFloatConstant) op1;
                                UntypedIntOrFloatConstant uc2 = (UntypedIntOrFloatConstant) op2;
                                // to int or float, it does not matter
                                be.setOp1(uc1.toIntConstant());
                                be.setOp2(uc2.toIntConstant());
                            } else if (op1 instanceof UntypedLongOrDoubleConstant && op2 instanceof UntypedLongOrDoubleConstant) {
                                UntypedLongOrDoubleConstant uc1 = (UntypedLongOrDoubleConstant) op1;
                                UntypedLongOrDoubleConstant uc2 = (UntypedLongOrDoubleConstant) op2;
                                // to long or double, it does not matter
                                be.setOp1(uc1.toLongConstant());
                                be.setOp2(uc2.toLongConstant());
                            } else {
                                throw new RuntimeException("error: expected same type of untyped constants. Got " + stmt);
                            }
                        } else if (op1 instanceof UntypedConstant || op2 instanceof UntypedConstant) {
                            if (op1 instanceof UntypedConstant) {
                                UntypedConstant uc = (UntypedConstant) op1;
                                be.setOp1(uc.defineType(op2.getType()));
                            } else if (op2 instanceof UntypedConstant) {
                                UntypedConstant uc = (UntypedConstant) op2;
                                be.setOp2(uc.defineType(op1.getType()));
                            }
                        } else {
                            throw new RuntimeException("error: expected local/untyped untyped/local or untyped/untyped. Got " + stmt);
                        }
                    }
                } else if (c instanceof UnopExpr) {
                } else {
                    throw new RuntimeException("error: expected binop or unop. Got " + stmt);
                }
            }

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

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

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

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

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

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

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

            @Override
            public void defaultCase(Object obj) {
            // TODO Auto-generated method stub
            }
        };
        u.apply(sw);
    }
// fix untyped constants remaining
// Debug.printDbg("assignTypes: after: \n", b);
}
Also used : AssignStmt(soot.jimple.AssignStmt) ArrayList(java.util.ArrayList) UnopExpr(soot.jimple.UnopExpr) SimpleLocalUses(soot.toolkits.scalar.SimpleLocalUses) ByteType(soot.ByteType) Unit(soot.Unit) LongOpTag(soot.dexpler.tags.LongOpTag) FloatType(soot.FloatType) ArrayType(soot.ArrayType) DoubleOpTag(soot.dexpler.tags.DoubleOpTag) TableSwitchStmt(soot.jimple.TableSwitchStmt) InstanceInvokeExpr(soot.jimple.InstanceInvokeExpr) DynamicInvokeExpr(soot.jimple.DynamicInvokeExpr) InvokeExpr(soot.jimple.InvokeExpr) StaticInvokeExpr(soot.jimple.StaticInvokeExpr) GotoStmt(soot.jimple.GotoStmt) CastExpr(soot.jimple.CastExpr) PrimType(soot.PrimType) List(java.util.List) ArrayList(java.util.ArrayList) EnterMonitorStmt(soot.jimple.EnterMonitorStmt) HashSet(java.util.HashSet) ShortType(soot.ShortType) Local(soot.Local) NewArrayExpr(soot.jimple.NewArrayExpr) Value(soot.Value) CharType(soot.CharType) ReturnStmt(soot.jimple.ReturnStmt) ThrowStmt(soot.jimple.ThrowStmt) DefinitionStmt(soot.jimple.DefinitionStmt) BinopExpr(soot.jimple.BinopExpr) SimpleLocalDefs(soot.toolkits.scalar.SimpleLocalDefs) ExitMonitorStmt(soot.jimple.ExitMonitorStmt) LongType(soot.LongType) InvokeStmt(soot.jimple.InvokeStmt) NullConstant(soot.jimple.NullConstant) Constant(soot.jimple.Constant) ReturnVoidStmt(soot.jimple.ReturnVoidStmt) IntOpTag(soot.dexpler.tags.IntOpTag) RetStmt(soot.jimple.RetStmt) BreakpointStmt(soot.jimple.BreakpointStmt) FloatOpTag(soot.dexpler.tags.FloatOpTag) IntType(soot.IntType) ArrayRef(soot.jimple.ArrayRef) ExceptionalUnitGraph(soot.toolkits.graph.ExceptionalUnitGraph) StmtSwitch(soot.jimple.StmtSwitch) UnitValueBoxPair(soot.toolkits.scalar.UnitValueBoxPair) IdentityStmt(soot.jimple.IdentityStmt) BooleanType(soot.BooleanType) LookupSwitchStmt(soot.jimple.LookupSwitchStmt) UnknownType(soot.UnknownType) RefType(soot.RefType) ShortType(soot.ShortType) BooleanType(soot.BooleanType) ByteType(soot.ByteType) Type(soot.Type) UnknownType(soot.UnknownType) DoubleType(soot.DoubleType) FloatType(soot.FloatType) IntType(soot.IntType) CharType(soot.CharType) LongType(soot.LongType) ArrayType(soot.ArrayType) PrimType(soot.PrimType) ExceptionalUnitGraph(soot.toolkits.graph.ExceptionalUnitGraph) UnitGraph(soot.toolkits.graph.UnitGraph) IfStmt(soot.jimple.IfStmt) ValueBox(soot.ValueBox) NopStmt(soot.jimple.NopStmt) DoubleType(soot.DoubleType) LongOpTag(soot.dexpler.tags.LongOpTag) Tag(soot.tagkit.Tag) DoubleOpTag(soot.dexpler.tags.DoubleOpTag) IntOpTag(soot.dexpler.tags.IntOpTag) FloatOpTag(soot.dexpler.tags.FloatOpTag)

Example 7 with LongType

use of soot.LongType in project soot by Sable.

the class TypeCastingError method inASTStatementSequenceNode.

public void inASTStatementSequenceNode(ASTStatementSequenceNode node) {
    for (AugmentedStmt as : node.getStatements()) {
        Stmt s = as.get_Stmt();
        if (!(s instanceof DefinitionStmt))
            continue;
        DefinitionStmt ds = (DefinitionStmt) s;
        if (myDebug)
            System.out.println("Definition stmt" + ds);
        ValueBox rightBox = ds.getRightOpBox();
        ValueBox leftBox = ds.getLeftOpBox();
        Value right = rightBox.getValue();
        Value left = leftBox.getValue();
        if (!(left.getType() instanceof PrimType && right.getType() instanceof PrimType)) {
            // only interested in prim type casting errors
            if (myDebug)
                System.out.println("\tDefinition stmt does not contain prims no need to modify");
            continue;
        }
        Type leftType = left.getType();
        Type rightType = right.getType();
        if (myDebug)
            System.out.println("Left type is: " + leftType);
        if (myDebug)
            System.out.println("Right type is: " + rightType);
        if (leftType.equals(rightType)) {
            if (myDebug)
                System.out.println("\tTypes are the same");
            if (myDebug)
                System.out.println("Right value is of instance" + right.getClass());
        }
        if (!leftType.equals(rightType)) {
            if (myDebug)
                System.out.println("\tDefinition stmt has to be modified");
            /*
				 * byte  	 Byte-length integer  	8-bit two's complement
				 * short 	Short integer 	16-bit two's complement
				 * int 	Integer 	32-bit two's complement
				 * long 	Long integer 	64-bit two's complement
				 * float 	Single-precision floating point 	32-bit IEEE 754
				 * double Double-precision floating point  	64-bit IEEE 754 	
				 */
            if (leftType instanceof ByteType && (rightType instanceof DoubleType || rightType instanceof FloatType || rightType instanceof IntType || rightType instanceof LongType || rightType instanceof ShortType)) {
                if (DEBUG)
                    System.out.println("Explicit casting to BYTE required");
                rightBox.setValue(new GCastExpr(right, ByteType.v()));
                if (DEBUG)
                    System.out.println("New right expr is " + rightBox.getValue().toString());
                continue;
            }
            if (leftType instanceof ShortType && (rightType instanceof DoubleType || rightType instanceof FloatType || rightType instanceof IntType || rightType instanceof LongType)) {
                if (DEBUG)
                    System.out.println("Explicit casting to SHORT required");
                rightBox.setValue(new GCastExpr(right, ShortType.v()));
                if (DEBUG)
                    System.out.println("New right expr is " + rightBox.getValue().toString());
                continue;
            }
            if (leftType instanceof IntType && (rightType instanceof DoubleType || rightType instanceof FloatType || rightType instanceof LongType)) {
                if (myDebug)
                    System.out.println("Explicit casting to INT required");
                rightBox.setValue(new GCastExpr(right, IntType.v()));
                if (myDebug)
                    System.out.println("New right expr is " + rightBox.getValue().toString());
                continue;
            }
            if (leftType instanceof LongType && (rightType instanceof DoubleType || rightType instanceof FloatType)) {
                if (DEBUG)
                    System.out.println("Explicit casting to LONG required");
                rightBox.setValue(new GCastExpr(right, LongType.v()));
                if (DEBUG)
                    System.out.println("New right expr is " + rightBox.getValue().toString());
                continue;
            }
            if (leftType instanceof FloatType && rightType instanceof DoubleType) {
                if (DEBUG)
                    System.out.println("Explicit casting to FLOAT required");
                rightBox.setValue(new GCastExpr(right, FloatType.v()));
                if (DEBUG)
                    System.out.println("New right expr is " + rightBox.getValue().toString());
                continue;
            }
        }
    }
}
Also used : LongType(soot.LongType) ShortType(soot.ShortType) ByteType(soot.ByteType) AugmentedStmt(soot.dava.internal.asg.AugmentedStmt) Stmt(soot.jimple.Stmt) AugmentedStmt(soot.dava.internal.asg.AugmentedStmt) DefinitionStmt(soot.jimple.DefinitionStmt) FloatType(soot.FloatType) IntType(soot.IntType) ByteType(soot.ByteType) DoubleType(soot.DoubleType) FloatType(soot.FloatType) IntType(soot.IntType) Type(soot.Type) PrimType(soot.PrimType) ShortType(soot.ShortType) LongType(soot.LongType) ValueBox(soot.ValueBox) DoubleType(soot.DoubleType) Value(soot.Value) PrimType(soot.PrimType) GCastExpr(soot.grimp.internal.GCastExpr) DefinitionStmt(soot.jimple.DefinitionStmt)

Example 8 with LongType

use of soot.LongType in project soot by Sable.

the class DavaPrinter method printTo.

public void printTo(SootClass cl, PrintWriter out) {
    // IterableSet packagesUsed = new IterableSet();
    IterableSet importList = new IterableSet();
    {
        String curPackage = cl.getJavaPackageName();
        if (!curPackage.equals("")) {
            out.println("package " + curPackage + ";");
            out.println();
        }
        if (cl.hasSuperclass()) {
            SootClass superClass = cl.getSuperclass();
            importList.add(superClass.toString());
        // packagesUsed.add(superClass.getJavaPackageName());
        }
        Iterator<SootClass> interfaceIt = cl.getInterfaces().iterator();
        while (interfaceIt.hasNext()) {
            String interfacePackage = ((SootClass) interfaceIt.next()).toString();
            if (!importList.contains(interfacePackage))
                importList.add(interfacePackage);
        // if (!packagesUsed.contains(interfacePackage))
        // packagesUsed.add(interfacePackage);
        }
        Iterator<SootMethod> methodIt = cl.methodIterator();
        while (methodIt.hasNext()) {
            SootMethod dm = (SootMethod) methodIt.next();
            if (dm.hasActiveBody()) {
                // packagesUsed = packagesUsed.union(((DavaBody) dm.getActiveBody()).get_PackagesUsed());
                importList = importList.union(((DavaBody) dm.getActiveBody()).getImportList());
            }
            Iterator<SootClass> eit = dm.getExceptions().iterator();
            while (eit.hasNext()) {
                String thrownPackage = eit.next().toString();
                if (!importList.contains(thrownPackage))
                    importList.add(thrownPackage);
            // if (!packagesUsed.contains(thrownPackage))
            // packagesUsed.add(thrownPackage);
            }
            Iterator<Type> pit = dm.getParameterTypes().iterator();
            while (pit.hasNext()) {
                Type t = (Type) pit.next();
                if (t instanceof RefType) {
                    String paramPackage = ((RefType) t).getSootClass().toString();
                    if (!importList.contains(paramPackage))
                        importList.add(paramPackage);
                // if (packagesUsed.contains(paramPackage) == false)
                // packagesUsed.add(paramPackage);
                }
            }
            Type t = dm.getReturnType();
            if (t instanceof RefType) {
                String returnPackage = ((RefType) t).getSootClass().toString();
                if (!importList.contains(returnPackage))
                    importList.add(returnPackage);
            // if (packagesUsed.contains(returnPackage) == false)
            // packagesUsed.add(returnPackage);
            }
        }
        Iterator<SootField> fieldIt = cl.getFields().iterator();
        while (fieldIt.hasNext()) {
            SootField f = (SootField) fieldIt.next();
            if (f.isPhantom())
                continue;
            Type t = f.getType();
            if (t instanceof RefType) {
                String fieldPackage = ((RefType) t).getSootClass().toString();
                if (!importList.contains(fieldPackage))
                    importList.add(fieldPackage);
            }
        }
        Iterator<String> pit = importList.iterator();
        List<String> toImport = new ArrayList<String>();
        while (pit.hasNext()) {
            /*
            	 * dont import any file which has currentPackage.className
            	 * dont import any file which starts with java.lang
            	 */
            String temp = (String) pit.next();
            // System.out.println("temp is "+temp);
            if (temp.indexOf("java.lang") > -1) {
                // problem is that we need to import sub packages java.lang.ref
                // for instance if the type is java.lang.ref.WeakReference
                String tempClassName = RemoveFullyQualifiedName.getClassName(temp);
                if (temp.equals("java.lang." + tempClassName)) {
                    // System.out.println("temp was not printed as it belongs to java.lang");
                    continue;
                }
            }
            if (curPackage.length() > 0 && temp.indexOf(curPackage) > -1) {
                // System.out.println("here  "+temp);
                continue;
            }
            if (cl.toString().equals(temp))
                continue;
            // System.out.println("printing"+);
            toImport.add(temp);
        }
        /*
             * Check that we are not importing two classes with the same last name
             * If yes then remove explicit import and import the whole package
             * else output explicit import statement
             */
        Iterator it = toImport.iterator();
        while (it.hasNext()) {
            String temp = (String) it.next();
            if (RemoveFullyQualifiedName.containsMultiple(toImport.iterator(), temp, null)) {
                // import package add *
                if (temp.lastIndexOf('.') > -1) {
                    temp = temp.substring(0, temp.lastIndexOf('.'));
                    out.println("import " + temp + ".*;");
                } else
                    throw new DecompilationException("Cant find the DOT . for fullyqualified name");
            } else {
                if (temp.lastIndexOf('.') == -1) {
                // dot not found this is a class belonging to this package so dont add
                } else
                    out.println("import " + temp + ";");
            }
        }
        boolean addNewLine = false;
        addNewLine = true;
        if (addNewLine)
            out.println();
        /*if (!packagesUsed.isEmpty())
                out.println();

            packagesUsed.add("java.lang");
            packagesUsed.add(curPackage);
            */
        Dava.v().set_CurrentPackageContext(importList);
        // Dava.v().set_CurrentPackageContext(packagesUsed);
        Dava.v().set_CurrentPackage(curPackage);
    }
    // Print class name + modifiers
    {
        String classPrefix = "";
        classPrefix = classPrefix + " " + Modifier.toString(cl.getModifiers());
        classPrefix = classPrefix.trim();
        if (!cl.isInterface()) {
            classPrefix = classPrefix + " class";
            classPrefix = classPrefix.trim();
        }
        out.print(classPrefix + " " + cl.getShortJavaStyleName());
    }
    // Print extension
    if (cl.hasSuperclass() && !(cl.getSuperclass().getName().equals("java.lang.Object"))) {
        String superClassName = cl.getSuperclass().getName();
        // Nomair Naeem 8th Feb 2006
        // also check if the super class name is not a fully qualified
        // name. in which case if the package is imported no need for
        // the long name
        superClassName = RemoveFullyQualifiedName.getReducedName(importList, superClassName, cl.getType());
        out.print(" extends " + superClassName + "");
    }
    // Print interfaces
    {
        Iterator<SootClass> interfaceIt = cl.getInterfaces().iterator();
        if (interfaceIt.hasNext()) {
            if (cl.isInterface())
                out.print(" extends ");
            else
                out.print(" implements ");
            out.print("" + (interfaceIt.next()).getName() + "");
            while (interfaceIt.hasNext()) out.print(", " + (interfaceIt.next()).getName() + "");
        }
    }
    out.println();
    out.println("{");
    // Print fields
    {
        Iterator<SootField> fieldIt = cl.getFields().iterator();
        if (fieldIt.hasNext()) {
            while (fieldIt.hasNext()) {
                SootField f = fieldIt.next();
                if (f.isPhantom())
                    continue;
                String declaration = null;
                Type fieldType = f.getType();
                String qualifiers = Modifier.toString(f.getModifiers()) + " ";
                qualifiers += RemoveFullyQualifiedName.getReducedName(importList, fieldType.toString(), fieldType);
                qualifiers = qualifiers.trim();
                if (qualifiers.equals(""))
                    declaration = Scene.v().quotedNameOf(f.getName());
                else
                    declaration = qualifiers + " " + Scene.v().quotedNameOf(f.getName()) + "";
                if (f.isFinal() && f.isStatic()) {
                    if (fieldType instanceof DoubleType && f.hasTag("DoubleConstantValueTag")) {
                        double val = ((DoubleConstantValueTag) f.getTag("DoubleConstantValueTag")).getDoubleValue();
                        out.println("    " + declaration + " = " + val + ";");
                    } else if (fieldType instanceof FloatType && f.hasTag("FloatConstantValueTag")) {
                        float val = ((FloatConstantValueTag) f.getTag("FloatConstantValueTag")).getFloatValue();
                        out.println("    " + declaration + " = " + val + "f;");
                    } else if (fieldType instanceof LongType && f.hasTag("LongConstantValueTag")) {
                        long val = ((LongConstantValueTag) f.getTag("LongConstantValueTag")).getLongValue();
                        out.println("    " + declaration + " = " + val + "l;");
                    } else if (fieldType instanceof CharType && f.hasTag("IntegerConstantValueTag")) {
                        int val = ((IntegerConstantValueTag) f.getTag("IntegerConstantValueTag")).getIntValue();
                        out.println("    " + declaration + " = '" + ((char) val) + "';");
                    } else if (fieldType instanceof BooleanType && f.hasTag("IntegerConstantValueTag")) {
                        int val = ((IntegerConstantValueTag) f.getTag("IntegerConstantValueTag")).getIntValue();
                        if (val == 0)
                            out.println("    " + declaration + " = false;");
                        else
                            out.println("    " + declaration + " = true;");
                    } else if ((fieldType instanceof IntType || fieldType instanceof ByteType || fieldType instanceof ShortType) && f.hasTag("IntegerConstantValueTag")) {
                        int val = ((IntegerConstantValueTag) f.getTag("IntegerConstantValueTag")).getIntValue();
                        out.println("    " + declaration + " = " + val + ";");
                    } else if (f.hasTag("StringConstantValueTag")) {
                        String val = ((StringConstantValueTag) f.getTag("StringConstantValueTag")).getStringValue();
                        out.println("    " + declaration + " = \"" + val + "\";");
                    } else {
                        // System.out.println("Couldnt find type of
                        // field"+f.getDeclaration());
                        out.println("    " + declaration + ";");
                    }
                } else // field is static final
                {
                    out.println("    " + declaration + ";");
                }
            }
        }
    }
    // Print methods
    {
        Iterator<SootMethod> methodIt = cl.methodIterator();
        if (methodIt.hasNext()) {
            if (cl.getMethodCount() != 0)
                out.println();
            while (methodIt.hasNext()) {
                SootMethod method = (SootMethod) methodIt.next();
                if (method.isPhantom())
                    continue;
                if (!Modifier.isAbstract(method.getModifiers()) && !Modifier.isNative(method.getModifiers())) {
                    if (!method.hasActiveBody())
                        throw new RuntimeException("method " + method.getName() + " has no active body!");
                    else
                        printTo(method.getActiveBody(), out);
                    if (methodIt.hasNext())
                        out.println();
                } else {
                    // if method is abstract then print the declaration
                    out.print("    ");
                    out.print(method.getDavaDeclaration());
                    out.println(";");
                    if (methodIt.hasNext())
                        out.println();
                }
            }
        }
    }
    if (G.v().SootClassNeedsDavaSuperHandlerClass.contains(cl)) {
        out.println("\n    private static class DavaSuperHandler{");
        out.println("         java.util.Vector myVector = new java.util.Vector();");
        out.println("\n         public Object get(int pos){");
        out.println("            return myVector.elementAt(pos);");
        out.println("         }");
        out.println("\n         public void store(Object obj){");
        out.println("            myVector.add(obj);");
        out.println("         }");
        out.println("    }");
    }
    out.println("}");
}
Also used : LongType(soot.LongType) ShortType(soot.ShortType) BooleanType(soot.BooleanType) IntegerConstantValueTag(soot.tagkit.IntegerConstantValueTag) ByteType(soot.ByteType) IterableSet(soot.util.IterableSet) SootClass(soot.SootClass) FloatType(soot.FloatType) IntType(soot.IntType) RefType(soot.RefType) RefType(soot.RefType) DoubleType(soot.DoubleType) FloatType(soot.FloatType) IntType(soot.IntType) ShortType(soot.ShortType) CharType(soot.CharType) LongType(soot.LongType) BooleanType(soot.BooleanType) ByteType(soot.ByteType) Type(soot.Type) DoubleType(soot.DoubleType) Iterator(java.util.Iterator) SootMethod(soot.SootMethod) SootField(soot.SootField) ArrayList(java.util.ArrayList) List(java.util.List) CharType(soot.CharType) FloatConstantValueTag(soot.tagkit.FloatConstantValueTag)

Example 9 with LongType

use of soot.LongType in project soot by Sable.

the class ExprVisitor method caseNegExpr.

@Override
public void caseNegExpr(NegExpr ne) {
    Value source = ne.getOp();
    constantV.setOrigStmt(origStmt);
    Register sourceReg = regAlloc.asImmediate(source, constantV);
    Opcode opc;
    Type type = source.getType();
    if (type instanceof IntegerType) {
        opc = Opcode.NEG_INT;
    } else if (type instanceof FloatType) {
        opc = Opcode.NEG_FLOAT;
    } else if (type instanceof DoubleType) {
        opc = Opcode.NEG_DOUBLE;
    } else if (type instanceof LongType) {
        opc = Opcode.NEG_LONG;
    } else {
        throw new RuntimeException("unsupported value type for neg-* opcode: " + type);
    }
    stmtV.addInsn(new Insn12x(opc, destinationReg, sourceReg), origStmt);
}
Also used : IntegerType(soot.IntegerType) RefType(soot.RefType) Type(soot.Type) DoubleType(soot.DoubleType) FloatType(soot.FloatType) IntType(soot.IntType) LongType(soot.LongType) NullType(soot.NullType) ArrayType(soot.ArrayType) IntegerType(soot.IntegerType) PrimType(soot.PrimType) LongType(soot.LongType) Insn12x(soot.toDex.instructions.Insn12x) DoubleType(soot.DoubleType) Value(soot.Value) Opcode(org.jf.dexlib2.Opcode) FloatType(soot.FloatType)

Example 10 with LongType

use of soot.LongType in project soot by Sable.

the class ArithmeticTransformer method internalTransform.

protected void internalTransform(Body b, String phaseName, Map<String, String> options) {
    int weight = soot.jbco.Main.getWeight(phaseName, b.getMethod().getSignature());
    if (weight == 0) {
        return;
    }
    PatchingChain<Unit> units = b.getUnits();
    int localCount = 0;
    Chain<Local> locals = b.getLocals();
    if (output) {
        out.println("*** Performing Arithmetic Transformation on " + b.getMethod().getSignature());
    }
    Iterator<Unit> it = units.snapshotIterator();
    while (it.hasNext()) {
        Unit u = it.next();
        if (u instanceof AssignStmt) {
            AssignStmt as = (AssignStmt) u;
            Value v = as.getRightOp();
            if (v instanceof MulExpr) {
                total++;
                MulExpr me = (MulExpr) v;
                Value op1 = me.getOp1();
                Value op = null, op2 = me.getOp2();
                NumericConstant nc = null;
                if (op1 instanceof NumericConstant) {
                    nc = (NumericConstant) op1;
                    op = op2;
                } else if (op2 instanceof NumericConstant) {
                    nc = (NumericConstant) op2;
                    op = op1;
                }
                if (nc != null) {
                    if (output) {
                        out.println("Considering: " + as + "\r");
                    }
                    Type opType = op.getType();
                    int max = opType instanceof IntType ? 32 : opType instanceof LongType ? 64 : 0;
                    if (max != 0) {
                        Object[] shft_rem = checkNumericValue(nc);
                        if (shft_rem[0] != null && (Integer) shft_rem[0] < max && Rand.getInt(10) <= weight) {
                            List<Unit> unitsBuilt = new ArrayList<>();
                            int rand = Rand.getInt(16);
                            int shift = (Integer) shft_rem[0];
                            boolean neg = (Boolean) shft_rem[2];
                            if (rand % 2 == 0) {
                                shift += rand * max;
                            } else {
                                shift -= rand * max;
                            }
                            Expr e;
                            if (shft_rem[1] != null) {
                                // if there is an additive floating component
                                Local tmp2 = null, tmp1 = Jimple.v().newLocal("__tmp_shft_lcl" + localCount++, opType);
                                locals.add(tmp1);
                                // shift the integral portion
                                Unit newU = Jimple.v().newAssignStmt(tmp1, Jimple.v().newShlExpr(op, IntConstant.v(shift)));
                                unitsBuilt.add(newU);
                                units.insertBefore(newU, u);
                                // grab remainder (that not part of the 2^x)
                                double rem = (Double) shft_rem[1];
                                if (rem != 1) {
                                    if (rem == ((int) rem) && opType instanceof IntType) {
                                        nc = IntConstant.v((int) rem);
                                    } else if (rem == ((long) rem) && opType instanceof LongType) {
                                        nc = LongConstant.v((long) rem);
                                    } else {
                                        nc = DoubleConstant.v(rem);
                                    }
                                    if (nc instanceof DoubleConstant) {
                                        tmp2 = Jimple.v().newLocal("__tmp_shft_lcl" + localCount++, DoubleType.v());
                                        locals.add(tmp2);
                                        newU = Jimple.v().newAssignStmt(tmp2, Jimple.v().newCastExpr(op, DoubleType.v()));
                                        unitsBuilt.add(newU);
                                        units.insertBefore(newU, u);
                                        newU = Jimple.v().newAssignStmt(tmp2, Jimple.v().newMulExpr(tmp2, nc));
                                    } else {
                                        tmp2 = Jimple.v().newLocal("__tmp_shft_lcl" + localCount++, nc.getType());
                                        locals.add(tmp2);
                                        newU = Jimple.v().newAssignStmt(tmp2, Jimple.v().newMulExpr(op, nc));
                                    }
                                    unitsBuilt.add(newU);
                                    units.insertBefore(newU, u);
                                }
                                if (tmp2 == null) {
                                    e = Jimple.v().newAddExpr(tmp1, op);
                                } else if (tmp2.getType().getClass() != tmp1.getType().getClass()) {
                                    Local tmp3 = Jimple.v().newLocal("__tmp_shft_lcl" + localCount++, tmp2.getType());
                                    locals.add(tmp3);
                                    newU = Jimple.v().newAssignStmt(tmp3, Jimple.v().newCastExpr(tmp1, tmp2.getType()));
                                    unitsBuilt.add(newU);
                                    units.insertBefore(newU, u);
                                    e = Jimple.v().newAddExpr(tmp3, tmp2);
                                } else {
                                    e = Jimple.v().newAddExpr(tmp1, tmp2);
                                }
                            } else {
                                e = Jimple.v().newShlExpr(op, IntConstant.v(shift));
                            }
                            if (e.getType().getClass() != as.getLeftOp().getType().getClass()) {
                                Local tmp = Jimple.v().newLocal("__tmp_shft_lcl" + localCount++, e.getType());
                                locals.add(tmp);
                                Unit newU = Jimple.v().newAssignStmt(tmp, e);
                                unitsBuilt.add(newU);
                                units.insertAfter(newU, u);
                                e = Jimple.v().newCastExpr(tmp, as.getLeftOp().getType());
                            }
                            as.setRightOp(e);
                            unitsBuilt.add(as);
                            if (neg) {
                                Unit newU = Jimple.v().newAssignStmt(as.getLeftOp(), Jimple.v().newNegExpr(as.getLeftOp()));
                                unitsBuilt.add(newU);
                                units.insertAfter(newU, u);
                            }
                            mulPerformed++;
                            printOutput(unitsBuilt);
                        }
                    }
                }
            } else if (v instanceof DivExpr) {
                total++;
                DivExpr de = (DivExpr) v;
                Value op2 = de.getOp2();
                NumericConstant nc;
                if (op2 instanceof NumericConstant) {
                    nc = (NumericConstant) op2;
                    Type opType = de.getOp1().getType();
                    int max = opType instanceof IntType ? 32 : opType instanceof LongType ? 64 : 0;
                    if (max != 0) {
                        Object[] shft_rem = checkNumericValue(nc);
                        if (shft_rem[0] != null && (shft_rem[1] == null || (Double) shft_rem[1] == 0) && (Integer) shft_rem[0] < max && Rand.getInt(10) <= weight) {
                            List<Unit> unitsBuilt = new ArrayList<>();
                            int rand = Rand.getInt(16);
                            int shift = (Integer) shft_rem[0];
                            boolean neg = (Boolean) shft_rem[2];
                            if (Rand.getInt() % 2 == 0) {
                                shift += rand * max;
                            } else {
                                shift -= rand * max;
                            }
                            Expr e = Jimple.v().newShrExpr(de.getOp1(), IntConstant.v(shift));
                            if (e.getType().getClass() != as.getLeftOp().getType().getClass()) {
                                Local tmp = Jimple.v().newLocal("__tmp_shft_lcl" + localCount++, e.getType());
                                locals.add(tmp);
                                Unit newU = Jimple.v().newAssignStmt(tmp, e);
                                unitsBuilt.add(newU);
                                units.insertAfter(newU, u);
                                e = Jimple.v().newCastExpr(tmp, as.getLeftOp().getType());
                            }
                            as.setRightOp(e);
                            unitsBuilt.add(as);
                            if (neg) {
                                Unit newU = Jimple.v().newAssignStmt(as.getLeftOp(), Jimple.v().newNegExpr(as.getLeftOp()));
                                unitsBuilt.add(newU);
                                units.insertAfter(newU, u);
                            }
                            divPerformed++;
                            printOutput(unitsBuilt);
                        }
                    }
                }
            }
        }
    }
}
Also used : MulExpr(soot.jimple.MulExpr) DoubleConstant(soot.jimple.DoubleConstant) LongType(soot.LongType) AssignStmt(soot.jimple.AssignStmt) ArrayList(java.util.ArrayList) Unit(soot.Unit) IntType(soot.IntType) ArrayList(java.util.ArrayList) List(java.util.List) Local(soot.Local) DoubleType(soot.DoubleType) IntType(soot.IntType) LongType(soot.LongType) Type(soot.Type) DivExpr(soot.jimple.DivExpr) MulExpr(soot.jimple.MulExpr) Expr(soot.jimple.Expr) DivExpr(soot.jimple.DivExpr) NumericConstant(soot.jimple.NumericConstant) Value(soot.Value)

Aggregations

LongType (soot.LongType)17 DoubleType (soot.DoubleType)16 IntType (soot.IntType)16 Type (soot.Type)15 FloatType (soot.FloatType)14 ByteType (soot.ByteType)12 ShortType (soot.ShortType)12 BooleanType (soot.BooleanType)11 CharType (soot.CharType)11 Value (soot.Value)11 ArrayList (java.util.ArrayList)10 Local (soot.Local)10 RefType (soot.RefType)9 List (java.util.List)7 ArrayType (soot.ArrayType)7 NullType (soot.NullType)6 IntConstant (soot.jimple.IntConstant)6 PrimType (soot.PrimType)5 Unit (soot.Unit)5 ValueBox (soot.ValueBox)5