Search in sources :

Example 1 with ByteType

use of soot.ByteType in project soot by Sable.

the class GroupIntPair method emitInst.

void emitInst(Inst inst) {
    LineNumberTag lnTag = (LineNumberTag) inst.getTag("LineNumberTag");
    if (lnTag != null)
        emit(".line " + lnTag.getLineNumber());
    inst.apply(new InstSwitch() {

        @Override
        public void caseReturnVoidInst(ReturnVoidInst i) {
            emit("return");
        }

        @Override
        public void caseReturnInst(ReturnInst i) {
            i.getOpType().apply(new TypeSwitch() {

                @Override
                public void defaultCase(Type t) {
                    throw new RuntimeException("invalid return type " + t.toString());
                }

                @Override
                public void caseDoubleType(DoubleType t) {
                    emit("dreturn");
                }

                @Override
                public void caseFloatType(FloatType t) {
                    emit("freturn");
                }

                @Override
                public void caseIntType(IntType t) {
                    emit("ireturn");
                }

                @Override
                public void caseByteType(ByteType t) {
                    emit("ireturn");
                }

                @Override
                public void caseShortType(ShortType t) {
                    emit("ireturn");
                }

                @Override
                public void caseCharType(CharType t) {
                    emit("ireturn");
                }

                @Override
                public void caseBooleanType(BooleanType t) {
                    emit("ireturn");
                }

                @Override
                public void caseLongType(LongType t) {
                    emit("lreturn");
                }

                @Override
                public void caseArrayType(ArrayType t) {
                    emit("areturn");
                }

                @Override
                public void caseRefType(RefType t) {
                    emit("areturn");
                }

                @Override
                public void caseNullType(NullType t) {
                    emit("areturn");
                }
            });
        }

        @Override
        public void caseNopInst(NopInst i) {
            emit("nop");
        }

        @Override
        public void caseEnterMonitorInst(EnterMonitorInst i) {
            emit("monitorenter");
        }

        @Override
        public void casePopInst(PopInst i) {
            if (i.getWordCount() == 2) {
                emit("pop2");
            } else
                emit("pop");
        }

        @Override
        public void caseExitMonitorInst(ExitMonitorInst i) {
            emit("monitorexit");
        }

        @Override
        public void caseGotoInst(GotoInst i) {
            emit("goto " + unitToLabel.get(i.getTarget()));
        }

        @Override
        public void caseJSRInst(JSRInst i) {
            emit("jsr " + unitToLabel.get(i.getTarget()));
        }

        @Override
        public void casePushInst(PushInst i) {
            if (i.getConstant() instanceof IntConstant) {
                IntConstant v = (IntConstant) (i.getConstant());
                if (v.value == -1)
                    emit("iconst_m1");
                else if (v.value >= 0 && v.value <= 5)
                    emit("iconst_" + v.value);
                else if (v.value >= Byte.MIN_VALUE && v.value <= Byte.MAX_VALUE)
                    emit("bipush " + v.value);
                else if (v.value >= Short.MIN_VALUE && v.value <= Short.MAX_VALUE)
                    emit("sipush " + v.value);
                else
                    emit("ldc " + v.toString());
            } else if (i.getConstant() instanceof StringConstant) {
                emit("ldc " + i.getConstant().toString());
            } else if (i.getConstant() instanceof ClassConstant) {
                emit("ldc_w " + ((ClassConstant) i.getConstant()).getValue());
            } else if (i.getConstant() instanceof DoubleConstant) {
                DoubleConstant v = (DoubleConstant) (i.getConstant());
                if ((v.value == 0) && ((1.0 / v.value) > 0.0))
                    emit("dconst_0");
                else if (v.value == 1)
                    emit("dconst_1");
                else {
                    String s = doubleToString(v);
                    emit("ldc2_w " + s);
                }
            } else if (i.getConstant() instanceof FloatConstant) {
                FloatConstant v = (FloatConstant) (i.getConstant());
                if ((v.value == 0) && ((1.0f / v.value) > 1.0f))
                    emit("fconst_0");
                else if (v.value == 1)
                    emit("fconst_1");
                else if (v.value == 2)
                    emit("fconst_2");
                else {
                    String s = floatToString(v);
                    emit("ldc " + s);
                }
            } else if (i.getConstant() instanceof LongConstant) {
                LongConstant v = (LongConstant) (i.getConstant());
                if (v.value == 0)
                    emit("lconst_0");
                else if (v.value == 1)
                    emit("lconst_1");
                else
                    emit("ldc2_w " + v.toString());
            } else if (i.getConstant() instanceof NullConstant) {
                emit("aconst_null");
            } else if (i.getConstant() instanceof MethodHandle) {
                throw new RuntimeException("MethodHandle constants not supported by Jasmin. Please use -asm-backend.");
            } else
                throw new RuntimeException("unsupported opcode");
        }

        @Override
        public void caseIdentityInst(IdentityInst i) {
            if (i.getRightOp() instanceof CaughtExceptionRef && i.getLeftOp() instanceof Local) {
                int slot = localToSlot.get(i.getLeftOp()).intValue();
                if (slot >= 0 && slot <= 3)
                    emit("astore_" + slot);
                else
                    emit("astore " + slot);
            }
        }

        @Override
        public void caseStoreInst(StoreInst i) {
            final int slot = localToSlot.get(i.getLocal()).intValue();
            i.getOpType().apply(new TypeSwitch() {

                @Override
                public void caseArrayType(ArrayType t) {
                    if (slot >= 0 && slot <= 3)
                        emit("astore_" + slot);
                    else
                        emit("astore " + slot);
                }

                @Override
                public void caseDoubleType(DoubleType t) {
                    if (slot >= 0 && slot <= 3)
                        emit("dstore_" + slot);
                    else
                        emit("dstore " + slot);
                }

                @Override
                public void caseFloatType(FloatType t) {
                    if (slot >= 0 && slot <= 3)
                        emit("fstore_" + slot);
                    else
                        emit("fstore " + slot);
                }

                @Override
                public void caseIntType(IntType t) {
                    if (slot >= 0 && slot <= 3)
                        emit("istore_" + slot);
                    else
                        emit("istore " + slot);
                }

                @Override
                public void caseByteType(ByteType t) {
                    if (slot >= 0 && slot <= 3)
                        emit("istore_" + slot);
                    else
                        emit("istore " + slot);
                }

                @Override
                public void caseShortType(ShortType t) {
                    if (slot >= 0 && slot <= 3)
                        emit("istore_" + slot);
                    else
                        emit("istore " + slot);
                }

                @Override
                public void caseCharType(CharType t) {
                    if (slot >= 0 && slot <= 3)
                        emit("istore_" + slot);
                    else
                        emit("istore " + slot);
                }

                @Override
                public void caseBooleanType(BooleanType t) {
                    if (slot >= 0 && slot <= 3)
                        emit("istore_" + slot);
                    else
                        emit("istore " + slot);
                }

                @Override
                public void caseLongType(LongType t) {
                    if (slot >= 0 && slot <= 3)
                        emit("lstore_" + slot);
                    else
                        emit("lstore " + slot);
                }

                @Override
                public void caseRefType(RefType t) {
                    if (slot >= 0 && slot <= 3)
                        emit("astore_" + slot);
                    else
                        emit("astore " + slot);
                }

                @Override
                public void caseStmtAddressType(StmtAddressType t) {
                    isNextGotoAJsr = true;
                    returnAddressSlot = slot;
                /*
						 * if ( slot >= 0 && slot <= 3) emit("astore_" + slot,
						 * ); else emit("astore " + slot, );
						 */
                }

                @Override
                public void caseNullType(NullType t) {
                    if (slot >= 0 && slot <= 3)
                        emit("astore_" + slot);
                    else
                        emit("astore " + slot);
                }

                @Override
                public void defaultCase(Type t) {
                    throw new RuntimeException("Invalid local type:" + t);
                }
            });
        }

        @Override
        public void caseLoadInst(LoadInst i) {
            final int slot = localToSlot.get(i.getLocal()).intValue();
            i.getOpType().apply(new TypeSwitch() {

                @Override
                public void caseArrayType(ArrayType t) {
                    if (slot >= 0 && slot <= 3)
                        emit("aload_" + slot);
                    else
                        emit("aload " + slot);
                }

                @Override
                public void defaultCase(Type t) {
                    throw new RuntimeException("invalid local type to load" + t);
                }

                @Override
                public void caseDoubleType(DoubleType t) {
                    if (slot >= 0 && slot <= 3)
                        emit("dload_" + slot);
                    else
                        emit("dload " + slot);
                }

                @Override
                public void caseFloatType(FloatType t) {
                    if (slot >= 0 && slot <= 3)
                        emit("fload_" + slot);
                    else
                        emit("fload " + slot);
                }

                @Override
                public void caseIntType(IntType t) {
                    if (slot >= 0 && slot <= 3)
                        emit("iload_" + slot);
                    else
                        emit("iload " + slot);
                }

                @Override
                public void caseByteType(ByteType t) {
                    if (slot >= 0 && slot <= 3)
                        emit("iload_" + slot);
                    else
                        emit("iload " + slot);
                }

                @Override
                public void caseShortType(ShortType t) {
                    if (slot >= 0 && slot <= 3)
                        emit("iload_" + slot);
                    else
                        emit("iload " + slot);
                }

                @Override
                public void caseCharType(CharType t) {
                    if (slot >= 0 && slot <= 3)
                        emit("iload_" + slot);
                    else
                        emit("iload " + slot);
                }

                @Override
                public void caseBooleanType(BooleanType t) {
                    if (slot >= 0 && slot <= 3)
                        emit("iload_" + slot);
                    else
                        emit("iload " + slot);
                }

                @Override
                public void caseLongType(LongType t) {
                    if (slot >= 0 && slot <= 3)
                        emit("lload_" + slot);
                    else
                        emit("lload " + slot);
                }

                @Override
                public void caseRefType(RefType t) {
                    if (slot >= 0 && slot <= 3)
                        emit("aload_" + slot);
                    else
                        emit("aload " + slot);
                }

                @Override
                public void caseNullType(NullType t) {
                    if (slot >= 0 && slot <= 3)
                        emit("aload_" + slot);
                    else
                        emit("aload " + slot);
                }
            });
        }

        @Override
        public void caseArrayWriteInst(ArrayWriteInst i) {
            i.getOpType().apply(new TypeSwitch() {

                @Override
                public void caseArrayType(ArrayType t) {
                    emit("aastore");
                }

                @Override
                public void caseDoubleType(DoubleType t) {
                    emit("dastore");
                }

                @Override
                public void caseFloatType(FloatType t) {
                    emit("fastore");
                }

                @Override
                public void caseIntType(IntType t) {
                    emit("iastore");
                }

                @Override
                public void caseLongType(LongType t) {
                    emit("lastore");
                }

                @Override
                public void caseRefType(RefType t) {
                    emit("aastore");
                }

                @Override
                public void caseByteType(ByteType t) {
                    emit("bastore");
                }

                @Override
                public void caseBooleanType(BooleanType t) {
                    emit("bastore");
                }

                @Override
                public void caseCharType(CharType t) {
                    emit("castore");
                }

                @Override
                public void caseShortType(ShortType t) {
                    emit("sastore");
                }

                @Override
                public void defaultCase(Type t) {
                    throw new RuntimeException("Invalid type: " + t);
                }
            });
        }

        @Override
        public void caseArrayReadInst(ArrayReadInst i) {
            i.getOpType().apply(new TypeSwitch() {

                @Override
                public void caseArrayType(ArrayType ty) {
                    emit("aaload");
                }

                @Override
                public void caseBooleanType(BooleanType ty) {
                    emit("baload");
                }

                @Override
                public void caseByteType(ByteType ty) {
                    emit("baload");
                }

                @Override
                public void caseCharType(CharType ty) {
                    emit("caload");
                }

                @Override
                public void defaultCase(Type ty) {
                    throw new RuntimeException("invalid base type");
                }

                @Override
                public void caseDoubleType(DoubleType ty) {
                    emit("daload");
                }

                @Override
                public void caseFloatType(FloatType ty) {
                    emit("faload");
                }

                @Override
                public void caseIntType(IntType ty) {
                    emit("iaload");
                }

                @Override
                public void caseLongType(LongType ty) {
                    emit("laload");
                }

                @Override
                public void caseNullType(NullType ty) {
                    emit("aaload");
                }

                @Override
                public void caseRefType(RefType ty) {
                    emit("aaload");
                }

                @Override
                public void caseShortType(ShortType ty) {
                    emit("saload");
                }
            });
        }

        @Override
        public void caseIfNullInst(IfNullInst i) {
            emit("ifnull " + unitToLabel.get(i.getTarget()));
        }

        @Override
        public void caseIfNonNullInst(IfNonNullInst i) {
            emit("ifnonnull " + unitToLabel.get(i.getTarget()));
        }

        @Override
        public void caseIfEqInst(IfEqInst i) {
            emit("ifeq " + unitToLabel.get(i.getTarget()));
        }

        @Override
        public void caseIfNeInst(IfNeInst i) {
            emit("ifne " + unitToLabel.get(i.getTarget()));
        }

        @Override
        public void caseIfGtInst(IfGtInst i) {
            emit("ifgt " + unitToLabel.get(i.getTarget()));
        }

        @Override
        public void caseIfGeInst(IfGeInst i) {
            emit("ifge " + unitToLabel.get(i.getTarget()));
        }

        @Override
        public void caseIfLtInst(IfLtInst i) {
            emit("iflt " + unitToLabel.get(i.getTarget()));
        }

        @Override
        public void caseIfLeInst(IfLeInst i) {
            emit("ifle " + unitToLabel.get(i.getTarget()));
        }

        @Override
        public void caseIfCmpEqInst(final IfCmpEqInst i) {
            i.getOpType().apply(new TypeSwitch() {

                @Override
                public void caseIntType(IntType t) {
                    emit("if_icmpeq " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseBooleanType(BooleanType t) {
                    emit("if_icmpeq " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseShortType(ShortType t) {
                    emit("if_icmpeq " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseCharType(CharType t) {
                    emit("if_icmpeq " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseByteType(ByteType t) {
                    emit("if_icmpeq " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseDoubleType(DoubleType t) {
                    emit("dcmpg");
                    emit("ifeq " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseLongType(LongType t) {
                    emit("lcmp");
                    emit("ifeq " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseFloatType(FloatType t) {
                    emit("fcmpg");
                    emit("ifeq " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseArrayType(ArrayType t) {
                    emit("if_acmpeq " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseRefType(RefType t) {
                    emit("if_acmpeq " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseNullType(NullType t) {
                    emit("if_acmpeq " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void defaultCase(Type t) {
                    throw new RuntimeException("invalid type");
                }
            });
        }

        @Override
        public void caseIfCmpNeInst(final IfCmpNeInst i) {
            i.getOpType().apply(new TypeSwitch() {

                @Override
                public void caseIntType(IntType t) {
                    emit("if_icmpne " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseBooleanType(BooleanType t) {
                    emit("if_icmpne " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseShortType(ShortType t) {
                    emit("if_icmpne " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseCharType(CharType t) {
                    emit("if_icmpne " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseByteType(ByteType t) {
                    emit("if_icmpne " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseDoubleType(DoubleType t) {
                    emit("dcmpg");
                    emit("ifne " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseLongType(LongType t) {
                    emit("lcmp");
                    emit("ifne " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseFloatType(FloatType t) {
                    emit("fcmpg");
                    emit("ifne " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseArrayType(ArrayType t) {
                    emit("if_acmpne " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseRefType(RefType t) {
                    emit("if_acmpne " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseNullType(NullType t) {
                    emit("if_acmpne " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void defaultCase(Type t) {
                    throw new RuntimeException("invalid type");
                }
            });
        }

        @Override
        public void caseIfCmpGtInst(final IfCmpGtInst i) {
            i.getOpType().apply(new TypeSwitch() {

                @Override
                public void caseIntType(IntType t) {
                    emit("if_icmpgt " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseBooleanType(BooleanType t) {
                    emit("if_icmpgt " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseShortType(ShortType t) {
                    emit("if_icmpgt " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseCharType(CharType t) {
                    emit("if_icmpgt " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseByteType(ByteType t) {
                    emit("if_icmpgt " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseDoubleType(DoubleType t) {
                    emit("dcmpg");
                    emit("ifgt " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseLongType(LongType t) {
                    emit("lcmp");
                    emit("ifgt " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseFloatType(FloatType t) {
                    emit("fcmpg");
                    emit("ifgt " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseArrayType(ArrayType t) {
                    emit("if_acmpgt " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseRefType(RefType t) {
                    emit("if_acmpgt " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseNullType(NullType t) {
                    emit("if_acmpgt " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void defaultCase(Type t) {
                    throw new RuntimeException("invalid type");
                }
            });
        }

        @Override
        public void caseIfCmpGeInst(final IfCmpGeInst i) {
            i.getOpType().apply(new TypeSwitch() {

                @Override
                public void caseIntType(IntType t) {
                    emit("if_icmpge " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseBooleanType(BooleanType t) {
                    emit("if_icmpge " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseShortType(ShortType t) {
                    emit("if_icmpge " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseCharType(CharType t) {
                    emit("if_icmpge " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseByteType(ByteType t) {
                    emit("if_icmpge " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseDoubleType(DoubleType t) {
                    emit("dcmpg");
                    emit("ifge " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseLongType(LongType t) {
                    emit("lcmp");
                    emit("ifge " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseFloatType(FloatType t) {
                    emit("fcmpg");
                    emit("ifge " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseArrayType(ArrayType t) {
                    emit("if_acmpge " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseRefType(RefType t) {
                    emit("if_acmpge " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseNullType(NullType t) {
                    emit("if_acmpge " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void defaultCase(Type t) {
                    throw new RuntimeException("invalid type");
                }
            });
        }

        @Override
        public void caseIfCmpLtInst(final IfCmpLtInst i) {
            i.getOpType().apply(new TypeSwitch() {

                @Override
                public void caseIntType(IntType t) {
                    emit("if_icmplt " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseBooleanType(BooleanType t) {
                    emit("if_icmplt " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseShortType(ShortType t) {
                    emit("if_icmplt " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseCharType(CharType t) {
                    emit("if_icmplt " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseByteType(ByteType t) {
                    emit("if_icmplt " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseDoubleType(DoubleType t) {
                    emit("dcmpg");
                    emit("iflt " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseLongType(LongType t) {
                    emit("lcmp");
                    emit("iflt " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseFloatType(FloatType t) {
                    emit("fcmpg");
                    emit("iflt " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseArrayType(ArrayType t) {
                    emit("if_acmplt " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseRefType(RefType t) {
                    emit("if_acmplt " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseNullType(NullType t) {
                    emit("if_acmplt " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void defaultCase(Type t) {
                    throw new RuntimeException("invalid type");
                }
            });
        }

        @Override
        public void caseIfCmpLeInst(final IfCmpLeInst i) {
            i.getOpType().apply(new TypeSwitch() {

                @Override
                public void caseIntType(IntType t) {
                    emit("if_icmple " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseBooleanType(BooleanType t) {
                    emit("if_icmple " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseShortType(ShortType t) {
                    emit("if_icmple " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseCharType(CharType t) {
                    emit("if_icmple " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseByteType(ByteType t) {
                    emit("if_icmple " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseDoubleType(DoubleType t) {
                    emit("dcmpg");
                    emit("ifle " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseLongType(LongType t) {
                    emit("lcmp");
                    emit("ifle " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseFloatType(FloatType t) {
                    emit("fcmpg");
                    emit("ifle " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseArrayType(ArrayType t) {
                    emit("if_acmple " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseRefType(RefType t) {
                    emit("if_acmple " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseNullType(NullType t) {
                    emit("if_acmple " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void defaultCase(Type t) {
                    throw new RuntimeException("invalid type");
                }
            });
        }

        @Override
        public void caseStaticGetInst(StaticGetInst i) {
            SootFieldRef field = i.getFieldRef();
            emit("getstatic " + slashify(field.declaringClass().getName()) + "/" + field.name() + " " + jasminDescriptorOf(field.type()));
        }

        @Override
        public void caseStaticPutInst(StaticPutInst i) {
            emit("putstatic " + slashify(i.getFieldRef().declaringClass().getName()) + "/" + i.getFieldRef().name() + " " + jasminDescriptorOf(i.getFieldRef().type()));
        }

        @Override
        public void caseFieldGetInst(FieldGetInst i) {
            emit("getfield " + slashify(i.getFieldRef().declaringClass().getName()) + "/" + i.getFieldRef().name() + " " + jasminDescriptorOf(i.getFieldRef().type()));
        }

        @Override
        public void caseFieldPutInst(FieldPutInst i) {
            emit("putfield " + slashify(i.getFieldRef().declaringClass().getName()) + "/" + i.getFieldRef().name() + " " + jasminDescriptorOf(i.getFieldRef().type()));
        }

        @Override
        public void caseInstanceCastInst(InstanceCastInst i) {
            Type castType = i.getCastType();
            if (castType instanceof RefType)
                emit("checkcast " + slashify(((RefType) castType).getClassName()));
            else if (castType instanceof ArrayType)
                emit("checkcast " + jasminDescriptorOf(castType));
        }

        @Override
        public void caseInstanceOfInst(InstanceOfInst i) {
            Type checkType = i.getCheckType();
            if (checkType instanceof RefType)
                emit("instanceof " + slashify(checkType.toString()));
            else if (checkType instanceof ArrayType)
                emit("instanceof " + jasminDescriptorOf(checkType));
        }

        @Override
        public void caseNewInst(NewInst i) {
            emit("new " + slashify(i.getBaseType().getClassName()));
        }

        @Override
        public void casePrimitiveCastInst(PrimitiveCastInst i) {
            emit(i.toString());
        }

        @Override
        public void caseDynamicInvokeInst(DynamicInvokeInst i) {
            SootMethodRef m = i.getMethodRef();
            SootMethodRef bsm = i.getBootstrapMethodRef();
            String bsmArgString = "";
            for (Iterator<Value> iterator = i.getBootstrapArgs().iterator(); iterator.hasNext(); ) {
                Value val = iterator.next();
                bsmArgString += "(" + jasminDescriptorOf(val.getType()) + ")";
                bsmArgString += escape(val.toString());
                if (iterator.hasNext())
                    bsmArgString += ",";
            }
            emit("invokedynamic \"" + m.name() + "\" " + jasminDescriptorOf(m) + " " + slashify(bsm.declaringClass().getName()) + "/" + bsm.name() + jasminDescriptorOf(bsm) + "(" + bsmArgString + ")");
        }

        private String escape(String bsmArgString) {
            return bsmArgString.replace(",", "\\comma").replace(" ", "\\blank").replace("\t", "\\tab").replace("\n", "\\newline");
        }

        @Override
        public void caseStaticInvokeInst(StaticInvokeInst i) {
            SootMethodRef m = i.getMethodRef();
            emit("invokestatic " + slashify(m.declaringClass().getName()) + "/" + m.name() + jasminDescriptorOf(m));
        }

        @Override
        public void caseVirtualInvokeInst(VirtualInvokeInst i) {
            SootMethodRef m = i.getMethodRef();
            emit("invokevirtual " + slashify(m.declaringClass().getName()) + "/" + m.name() + jasminDescriptorOf(m));
        }

        @Override
        public void caseInterfaceInvokeInst(InterfaceInvokeInst i) {
            SootMethodRef m = i.getMethodRef();
            emit("invokeinterface " + slashify(m.declaringClass().getName()) + "/" + m.name() + jasminDescriptorOf(m) + " " + (argCountOf(m) + 1));
        }

        @Override
        public void caseSpecialInvokeInst(SpecialInvokeInst i) {
            SootMethodRef m = i.getMethodRef();
            emit("invokespecial " + slashify(m.declaringClass().getName()) + "/" + m.name() + jasminDescriptorOf(m));
        }

        @Override
        public void caseThrowInst(ThrowInst i) {
            emit("athrow");
        }

        @Override
        public void caseCmpInst(CmpInst i) {
            emit("lcmp");
        }

        @Override
        public void caseCmplInst(CmplInst i) {
            if (i.getOpType().equals(FloatType.v()))
                emit("fcmpl");
            else
                emit("dcmpl");
        }

        @Override
        public void caseCmpgInst(CmpgInst i) {
            if (i.getOpType().equals(FloatType.v()))
                emit("fcmpg");
            else
                emit("dcmpg");
        }

        private void emitOpTypeInst(final String s, final OpTypeArgInst i) {
            i.getOpType().apply(new TypeSwitch() {

                private void handleIntCase() {
                    emit("i" + s);
                }

                @Override
                public void caseIntType(IntType t) {
                    handleIntCase();
                }

                @Override
                public void caseBooleanType(BooleanType t) {
                    handleIntCase();
                }

                @Override
                public void caseShortType(ShortType t) {
                    handleIntCase();
                }

                @Override
                public void caseCharType(CharType t) {
                    handleIntCase();
                }

                @Override
                public void caseByteType(ByteType t) {
                    handleIntCase();
                }

                @Override
                public void caseLongType(LongType t) {
                    emit("l" + s);
                }

                @Override
                public void caseDoubleType(DoubleType t) {
                    emit("d" + s);
                }

                @Override
                public void caseFloatType(FloatType t) {
                    emit("f" + s);
                }

                @Override
                public void defaultCase(Type t) {
                    throw new RuntimeException("Invalid argument type for div");
                }
            });
        }

        @Override
        public void caseAddInst(AddInst i) {
            emitOpTypeInst("add", i);
        }

        @Override
        public void caseDivInst(DivInst i) {
            emitOpTypeInst("div", i);
        }

        @Override
        public void caseSubInst(SubInst i) {
            emitOpTypeInst("sub", i);
        }

        @Override
        public void caseMulInst(MulInst i) {
            emitOpTypeInst("mul", i);
        }

        @Override
        public void caseRemInst(RemInst i) {
            emitOpTypeInst("rem", i);
        }

        @Override
        public void caseShlInst(ShlInst i) {
            emitOpTypeInst("shl", i);
        }

        @Override
        public void caseAndInst(AndInst i) {
            emitOpTypeInst("and", i);
        }

        @Override
        public void caseOrInst(OrInst i) {
            emitOpTypeInst("or", i);
        }

        @Override
        public void caseXorInst(XorInst i) {
            emitOpTypeInst("xor", i);
        }

        @Override
        public void caseShrInst(ShrInst i) {
            emitOpTypeInst("shr", i);
        }

        @Override
        public void caseUshrInst(UshrInst i) {
            emitOpTypeInst("ushr", i);
        }

        @Override
        public void caseIncInst(IncInst i) {
            if (i.getUseBoxes().get(0).getValue() != i.getDefBoxes().get(0).getValue())
                throw new RuntimeException("iinc def and use boxes don't match");
            emit("iinc " + localToSlot.get(i.getLocal()) + " " + i.getConstant());
        }

        @Override
        public void caseArrayLengthInst(ArrayLengthInst i) {
            emit("arraylength");
        }

        @Override
        public void caseNegInst(NegInst i) {
            emitOpTypeInst("neg", i);
        }

        @Override
        public void caseNewArrayInst(NewArrayInst i) {
            if (i.getBaseType() instanceof RefType)
                emit("anewarray " + slashify(((RefType) i.getBaseType()).getClassName()));
            else if (i.getBaseType() instanceof ArrayType)
                emit("anewarray " + jasminDescriptorOf(i.getBaseType()));
            else
                emit("newarray " + i.getBaseType().toString());
        }

        @Override
        public void caseNewMultiArrayInst(NewMultiArrayInst i) {
            emit("multianewarray " + jasminDescriptorOf(i.getBaseType()) + " " + i.getDimensionCount());
        }

        @Override
        public void caseLookupSwitchInst(LookupSwitchInst i) {
            emit("lookupswitch");
            List<IntConstant> lookupValues = i.getLookupValues();
            List<Unit> targets = i.getTargets();
            for (int j = 0; j < lookupValues.size(); j++) emit("  " + lookupValues.get(j) + " : " + unitToLabel.get(targets.get(j)));
            emit("  default : " + unitToLabel.get(i.getDefaultTarget()));
        }

        @Override
        public void caseTableSwitchInst(TableSwitchInst i) {
            emit("tableswitch " + i.getLowIndex() + " ; high = " + i.getHighIndex());
            List<Unit> targets = i.getTargets();
            for (int j = 0; j < targets.size(); j++) emit("  " + unitToLabel.get(targets.get(j)));
            emit("default : " + unitToLabel.get(i.getDefaultTarget()));
        }

        private boolean isDwordType(Type t) {
            return t instanceof LongType || t instanceof DoubleType || t instanceof DoubleWordType;
        }

        @Override
        public void caseDup1Inst(Dup1Inst i) {
            Type firstOpType = i.getOp1Type();
            if (isDwordType(firstOpType))
                // (form 2)
                emit("dup2");
            else
                emit("dup");
        }

        @Override
        public void caseDup2Inst(Dup2Inst i) {
            Type firstOpType = i.getOp1Type();
            Type secondOpType = i.getOp2Type();
            // Use a pair of insts to simulate them.
            if (isDwordType(firstOpType)) {
                // (form 2)
                emit("dup2");
                if (isDwordType(secondOpType)) {
                    // (form 2 -- by simulation)
                    emit("dup2");
                } else
                    // also a simulation
                    emit("dup");
            } else if (isDwordType(secondOpType)) {
                if (isDwordType(firstOpType)) {
                    // (form 2)
                    emit("dup2");
                } else
                    emit("dup");
                // (form 2 -- complete the simulation)
                emit("dup2");
            } else {
                // form 1
                emit("dup2");
            }
        }

        @Override
        public void caseDup1_x1Inst(Dup1_x1Inst i) {
            Type opType = i.getOp1Type();
            Type underType = i.getUnder1Type();
            if (isDwordType(opType)) {
                if (isDwordType(underType)) {
                    // (form 4)
                    emit("dup2_x2");
                } else
                    // (form 2)
                    emit("dup2_x1");
            } else {
                if (isDwordType(underType))
                    // (form 2)
                    emit("dup_x2");
                else
                    // (only one form)
                    emit("dup_x1");
            }
        }

        @Override
        public void caseDup1_x2Inst(Dup1_x2Inst i) {
            Type opType = i.getOp1Type();
            Type under1Type = i.getUnder1Type();
            Type under2Type = i.getUnder2Type();
            if (isDwordType(opType)) {
                if (!isDwordType(under1Type) && !isDwordType(under2Type))
                    // (form 2)
                    emit("dup2_x2");
                else
                    throw new RuntimeException("magic not implemented yet");
            } else {
                if (isDwordType(under1Type) || isDwordType(under2Type))
                    throw new RuntimeException("magic not implemented yet");
            }
            // (form 1)
            emit("dup_x2");
        }

        @Override
        public void caseDup2_x1Inst(Dup2_x1Inst i) {
            Type op1Type = i.getOp1Type();
            Type op2Type = i.getOp2Type();
            Type under1Type = i.getUnder1Type();
            /*
				 * From VM Spec: cat1 = category 1 (word type) cat2 = category 2
				 * (doubleword)
				 * 
				 * Form 1: [..., cat1_value3, cat1_value2, cat1_value1]->[...,
				 * cat1_value2, cat1_value1, cat1_value3, cat1_value2,
				 * cat1_value1] Form 2: [..., cat1_value2, cat2_value1]->[...,
				 * cat2_value1, cat1_value2, cat2_value1]
				 */
            if (isDwordType(under1Type)) {
                if (!isDwordType(op1Type) && !isDwordType(op2Type))
                    throw new RuntimeException("magic not implemented yet");
                else
                    // (form 3)
                    emit("dup2_x2");
            } else {
                if ((isDwordType(op1Type) && op2Type != null) || isDwordType(op2Type))
                    throw new RuntimeException("magic not implemented yet");
            }
            // (form 1)
            emit("dup2_x1");
        }

        @Override
        public void caseDup2_x2Inst(Dup2_x2Inst i) {
            Type op1Type = i.getOp1Type();
            Type op2Type = i.getOp2Type();
            Type under1Type = i.getUnder1Type();
            Type under2Type = i.getUnder2Type();
            // 07-20-2006 Michael Batchelder
            // NOW handling all types of dup2_x2
            /*
				 * From VM Spec: cat1 = category 1 (word type) cat2 = category 2
				 * (doubleword) Form 1: [..., cat1_value4, cat1_value3,
				 * cat1_value2, cat1_value1]->[..., cat1_value2, cat1_value1,
				 * cat1_value4, cat1_value3, cat1_value2, cat1_value1] Form 2:
				 * [..., cat1_value3, cat1_value2, cat2_value1]->[ ...,
				 * cat2_value1, cat1_value3, cat1_value2, cat2_value1] Form 3:
				 * [..., cat2_value3, cat1_value2, cat1_value1]->[...,
				 * cat1_value2, cat1_value1, cat2_value3, cat1_value2,
				 * cat1_value1] Form 4: [..., cat2_value2, cat2_value1]->[...,
				 * cat2_value1, cat2_value2, cat2_value1]
				 */
            boolean malformed = true;
            if (isDwordType(op1Type)) {
                if (op2Type == null && under1Type != null)
                    if ((under2Type == null && isDwordType(under1Type)) || (!isDwordType(under1Type) && under2Type != null && !isDwordType(under2Type)))
                        malformed = false;
            } else if (op1Type != null && op2Type != null && !isDwordType(op2Type)) {
                if ((under2Type == null && isDwordType(under1Type)) || (under1Type != null && !isDwordType(under1Type) && under2Type != null && !isDwordType(under2Type)))
                    malformed = false;
            }
            if (malformed)
                throw new RuntimeException("magic not implemented yet");
            // (form 1)
            emit("dup2_x2");
        }

        @Override
        public void caseSwapInst(SwapInst i) {
            emit("swap");
        }
    });
}
Also used : TypeSwitch(soot.TypeSwitch) ByteType(soot.ByteType) FloatType(soot.FloatType) LineNumberTag(soot.tagkit.LineNumberTag) ShortType(soot.ShortType) Local(soot.Local) IntType(soot.IntType) BooleanType(soot.BooleanType) RefType(soot.RefType) DoubleType(soot.DoubleType) FloatType(soot.FloatType) IntType(soot.IntType) ShortType(soot.ShortType) CharType(soot.CharType) LongType(soot.LongType) NullType(soot.NullType) StmtAddressType(soot.StmtAddressType) BooleanType(soot.BooleanType) ByteType(soot.ByteType) ArrayType(soot.ArrayType) Type(soot.Type) StmtAddressType(soot.StmtAddressType) ArrayType(soot.ArrayType) RefType(soot.RefType) List(java.util.List) SootFieldRef(soot.SootFieldRef) Value(soot.Value) CharType(soot.CharType) NullType(soot.NullType) LongType(soot.LongType) Iterator(java.util.Iterator) SootMethodRef(soot.SootMethodRef) DoubleType(soot.DoubleType)

Example 2 with ByteType

use of soot.ByteType in project soot by Sable.

the class ConstantFieldValueFinder method valuesForPrimTypeFields.

/*
	 * This method gives values to all the fields in all the classes if they can be determined statically
	 * We only care about fields which have primitive types
	 */
private void valuesForPrimTypeFields() {
    // go through all the classes
    Iterator classIt = appClasses.iterator();
    while (classIt.hasNext()) {
        SootClass s = (SootClass) classIt.next();
        debug("\nvaluesforPrimTypeFields", "Processing class " + s.getName());
        String declaringClass = s.getName();
        Iterator fieldIt = s.getFields().iterator();
        while (fieldIt.hasNext()) {
            SootField f = (SootField) fieldIt.next();
            String fieldName = f.getName();
            Type fieldType = f.getType();
            if (!(fieldType instanceof PrimType))
                continue;
            String combined = declaringClass + combiner + fieldName;
            classNameFieldNameToSootFieldMapping.put(combined, f);
            Object value = null;
            // check for constant value tags
            if (fieldType instanceof DoubleType && f.hasTag("DoubleConstantValueTag")) {
                double val = ((DoubleConstantValueTag) f.getTag("DoubleConstantValueTag")).getDoubleValue();
                value = new Double(val);
            } else if (fieldType instanceof FloatType && f.hasTag("FloatConstantValueTag")) {
                float val = ((FloatConstantValueTag) f.getTag("FloatConstantValueTag")).getFloatValue();
                value = new Float(val);
            } else if (fieldType instanceof LongType && f.hasTag("LongConstantValueTag")) {
                long val = ((LongConstantValueTag) f.getTag("LongConstantValueTag")).getLongValue();
                value = new Long(val);
            } else if (fieldType instanceof CharType && f.hasTag("IntegerConstantValueTag")) {
                int val = ((IntegerConstantValueTag) f.getTag("IntegerConstantValueTag")).getIntValue();
                value = new Integer(val);
            } else if (fieldType instanceof BooleanType && f.hasTag("IntegerConstantValueTag")) {
                int val = ((IntegerConstantValueTag) f.getTag("IntegerConstantValueTag")).getIntValue();
                if (val == 0)
                    value = new Boolean(false);
                else
                    value = new Boolean(true);
            } else if ((fieldType instanceof IntType || fieldType instanceof ByteType || fieldType instanceof ShortType) && f.hasTag("IntegerConstantValueTag")) {
                int val = ((IntegerConstantValueTag) f.getTag("IntegerConstantValueTag")).getIntValue();
                value = new Integer(val);
            }
            // if there was a constant value tag we have its value now
            if (value != null) {
                debug("TAGGED value found for field: " + combined);
                primTypeFieldValueToUse.put(combined, value);
                // continue with next field
                continue;
            }
            // see if the field was never assigned in which case it gets default values
            Object temp = fieldToValues.get(combined);
            if (temp == null) {
                if (fieldType instanceof DoubleType)
                    value = new Double(0);
                else if (fieldType instanceof FloatType)
                    value = new Float(0);
                else if (fieldType instanceof LongType)
                    value = new Long(0);
                else if (fieldType instanceof BooleanType)
                    value = new Boolean(false);
                else if ((fieldType instanceof IntType || fieldType instanceof ByteType || fieldType instanceof ShortType) || fieldType instanceof CharType) {
                    value = new Integer(0);
                } else
                    throw new DecompilationException("Unknown primitive type...please report to developer");
                primTypeFieldValueToUse.put(combined, value);
                debug("DEFAULT value for field: " + combined);
                // continue with next field
                continue;
            }
            // havent got a tag with value and havent use default since SOME method did define the field atleast once
            // there was some value assigned!!!!!!!!!
            debug("CHECKING USER ASSIGNED VALUES FOR: " + combined);
            ArrayList values = (ArrayList) temp;
            // check if they are all constants and that too the same constant
            Iterator it = values.iterator();
            NumericConstant tempConstant = null;
            while (it.hasNext()) {
                Value val = (Value) it.next();
                if (!(val instanceof NumericConstant)) {
                    tempConstant = null;
                    debug("Not numeric constant hence giving up");
                    break;
                }
                if (tempConstant == null) {
                    tempConstant = (NumericConstant) val;
                } else {
                    // check that this value is the same as previous
                    if (!tempConstant.equals(val)) {
                        tempConstant = null;
                        break;
                    }
                }
            }
            if (tempConstant == null) {
                // continue with next field cant do anything about this one
                continue;
            }
            if (tempConstant instanceof LongConstant) {
                Long tempVal = new Long(((LongConstant) tempConstant).value);
                if (tempVal.compareTo(new Long(0)) == 0)
                    primTypeFieldValueToUse.put(combined, tempVal);
                else
                    debug("Not assigning the agreed value since that is not the default value for " + combined);
            } else if (tempConstant instanceof DoubleConstant) {
                Double tempVal = new Double(((DoubleConstant) tempConstant).value);
                if (tempVal.compareTo(new Double(0)) == 0)
                    primTypeFieldValueToUse.put(combined, tempVal);
                else
                    debug("Not assigning the agreed value since that is not the default value for " + combined);
            } else if (tempConstant instanceof FloatConstant) {
                Float tempVal = new Float(((FloatConstant) tempConstant).value);
                if (tempVal.compareTo(new Float(0)) == 0)
                    primTypeFieldValueToUse.put(combined, tempVal);
                else
                    debug("Not assigning the agreed value since that is not the default value for " + combined);
            } else if (tempConstant instanceof IntConstant) {
                Integer tempVal = new Integer(((IntConstant) tempConstant).value);
                if (tempVal.compareTo(new Integer(0)) == 0) {
                    SootField tempField = classNameFieldNameToSootFieldMapping.get(combined);
                    if (tempField.getType() instanceof BooleanType) {
                        primTypeFieldValueToUse.put(combined, new Boolean(false));
                    // System.out.println("puttingvalue false for"+combined);
                    } else {
                        primTypeFieldValueToUse.put(combined, tempVal);
                    // System.out.println("puttingvalue 0 for"+combined);
                    }
                } else
                    debug("Not assigning the agreed value since that is not the default value for " + combined);
            } else {
                throw new DecompilationException("Un handled Numberic Constant....report to programmer");
            }
        }
    // all fields of the class
    }
// all classes
}
Also used : DoubleConstant(soot.jimple.DoubleConstant) LongType(soot.LongType) FloatConstant(soot.jimple.FloatConstant) ArrayList(java.util.ArrayList) DecompilationException(soot.dava.DecompilationException) ByteType(soot.ByteType) FloatType(soot.FloatType) IntType(soot.IntType) Iterator(java.util.Iterator) PrimType(soot.PrimType) LongConstantValueTag(soot.tagkit.LongConstantValueTag) IntConstant(soot.jimple.IntConstant) LongConstant(soot.jimple.LongConstant) ShortType(soot.ShortType) BooleanType(soot.BooleanType) IntegerConstantValueTag(soot.tagkit.IntegerConstantValueTag) DoubleConstantValueTag(soot.tagkit.DoubleConstantValueTag) SootClass(soot.SootClass) 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) PrimType(soot.PrimType) DoubleType(soot.DoubleType) NumericConstant(soot.jimple.NumericConstant) Value(soot.Value) SootField(soot.SootField) CharType(soot.CharType)

Example 3 with ByteType

use of soot.ByteType in project soot by Sable.

the class CP method createInitialInput.

/*
	 * constant fields added with KNOWN CONSTANT VALUE formals added with TOP
	 * locals added with 0 other fields IGNORED
	 */
public void createInitialInput() {
    initialInput = new ArrayList<CPTuple>();
    // adding constant fields
    initialInput.addAll(constantFieldTuples);
    // String className =
    // analyze.getDavaBody().getMethod().getDeclaringClass().getName();
    // adding formals
    formals = new ArrayList<CPTuple>();
    // System.out.println("Adding following formals: with TOP");
    Collection col = methodNode.getDavaBody().get_ParamMap().values();
    Iterator it = col.iterator();
    while (it.hasNext()) {
        Object temp = it.next();
        if (temp instanceof Local) {
            Local tempLocal = (Local) temp;
            if (!(tempLocal.getType() instanceof PrimType))
                continue;
            CPVariable newVar = new CPVariable(tempLocal);
            // new tuple set to top since this is a formal and we dont know
            // what value we will get into it
            CPTuple newTuple = new CPTuple(localClassName, newVar, true);
            initialInput.add(newTuple);
            formals.add(newTuple);
        // System.out.print("\t"+tempLocal.getName());
        }
    }
    // System.out.println();
    // adding locals
    List decLocals = methodNode.getDeclaredLocals();
    it = decLocals.iterator();
    locals = new ArrayList<CPTuple>();
    // System.out.println("Adding following locals with default values:");
    while (it.hasNext()) {
        Object temp = it.next();
        if (temp instanceof Local) {
            Local tempLocal = (Local) temp;
            Type localType = tempLocal.getType();
            if (!(localType instanceof PrimType))
                continue;
            CPVariable newVar = new CPVariable(tempLocal);
            // store the default value into this object
            Object value;
            // depending on its type
            if (localType instanceof BooleanType)
                value = new Boolean(false);
            else if (localType instanceof ByteType)
                value = new Integer(0);
            else if (localType instanceof CharType)
                value = new Integer(0);
            else if (localType instanceof DoubleType)
                value = new Double(0);
            else if (localType instanceof FloatType)
                value = new Float(0);
            else if (localType instanceof IntType)
                value = new Integer(0);
            else if (localType instanceof LongType)
                value = new Long(0);
            else if (localType instanceof ShortType)
                value = new Integer(0);
            else
                throw new DavaFlowAnalysisException("Unknown PrimType");
            CPTuple newTuple = new CPTuple(localClassName, newVar, value);
            /*
				 * Commenting the next line since we dont want initial Input to
				 * have any locals in it all locals are considered bottom
				 * initially
				 */
            // initialInput.add(newTuple);
            locals.add(newTuple);
        // System.out.print("\t"+tempLocal.getName());
        }
    // was a local
    }
// System.out.println();
}
Also used : LongType(soot.LongType) ShortType(soot.ShortType) BooleanType(soot.BooleanType) Local(soot.Local) ByteType(soot.ByteType) FloatType(soot.FloatType) IntType(soot.IntType) 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) PrimType(soot.PrimType) DavaFlowAnalysisException(soot.dava.DavaFlowAnalysisException) DoubleType(soot.DoubleType) Iterator(java.util.Iterator) Collection(java.util.Collection) PrimType(soot.PrimType) ArrayList(java.util.ArrayList) List(java.util.List) CharType(soot.CharType)

Example 4 with ByteType

use of soot.ByteType 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 5 with ByteType

use of soot.ByteType 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)

Aggregations

ByteType (soot.ByteType)15 ShortType (soot.ShortType)15 CharType (soot.CharType)14 IntType (soot.IntType)14 Type (soot.Type)14 BooleanType (soot.BooleanType)13 DoubleType (soot.DoubleType)12 FloatType (soot.FloatType)12 LongType (soot.LongType)12 Local (soot.Local)9 RefType (soot.RefType)8 ArrayList (java.util.ArrayList)7 ArrayType (soot.ArrayType)7 Value (soot.Value)7 List (java.util.List)6 Iterator (java.util.Iterator)4 NullType (soot.NullType)4 PrimType (soot.PrimType)4 SootClass (soot.SootClass)3 ValueBox (soot.ValueBox)3