Beispiel #1
0
        public void VisitBinary(BinaryOp op)
        {
            if (m_offset < 0 && (op.Untyped.OpCode.Code == Code.Div || op.Untyped.OpCode.Code == Code.Div_Un))
            {
                do
                {
                    LoadConstantInt load1 = m_info.Instructions[op.Index - 1] as LoadConstantInt;
                    if (load1 != null)
                    {
                        if (load1.Value == 0)
                        {
                            m_offset = op.Untyped.Offset;
                            Log.DebugLine(this, "zero constant denominator at {0:X2}", m_offset);
                        }
                        break;
                    }

                    LoadLocal load2 = m_info.Instructions[op.Index - 1] as LoadLocal;
                    if (load2 != null)
                    {
                        if (DoIsIntType(load2.Type))
                        {
                            State state = m_info.Tracker.State(op.Index - 1);
                            long? value = state.Locals[load2.Variable];
                            if (value.HasValue && value.Value == 0)
                            {
                                m_offset = op.Untyped.Offset;
                                Log.DebugLine(this, "zero local denominator at {0:X2}", m_offset);
                            }
                        }
                        break;
                    }

                    LoadArg load3 = m_info.Instructions[op.Index - 1] as LoadArg;
                    if (load3 != null)
                    {
                        if (DoIsIntType(load3.Type))
                        {
                            State state2 = m_info.Tracker.State(op.Index - 1);
                            long? value2 = state2.Arguments[m_info.Method.HasThis ? load3.Arg : load3.Arg - 1];
                            if (value2.HasValue && value2.Value == 0)
                            {
                                m_offset = op.Untyped.Offset;
                                Log.DebugLine(this, "zero arg denominator at {0:X2}", m_offset);
                            }
                        }
                        break;
                    }
                }while (false);
            }
        }
Beispiel #2
0
        private void DoCheck(MethodInfo info)
        {
            if (info.Instructions.Length == 2)
            {
                LoadConstantInt load = info.Instructions[0] as LoadConstantInt;
                End             end  = info.Instructions[1] as End;

                if (load != null && end != null && end.Untyped.OpCode.Code == Code.Ret)
                {
                    Log.DebugLine(this, "returns constant");
                    Reporter.MethodFailed(info.Method, CheckID, 0, string.Empty);
                }
            }
        }
Beispiel #3
0
        public void VisitNew(NewArr newer)
        {
            if (newer.Type.FullName == "System.Type")
            {
                Log.DebugLine(this, " new {0}[] at {1:X2}", newer.Type.FullName, newer.Untyped.Offset);

                LoadConstantInt load = m_info.Instructions[newer.Index - 1] as LoadConstantInt;
                if (load != null)
                {
                    if (load.Value == 0)
                    {
                        Reporter.MethodFailed(m_info.Method, CheckID, newer.Untyped.Offset, string.Empty);
                    }
                }
            }
        }
Beispiel #4
0
        public void VisitStore(StoreLocal store)
        {
            if (store.Index > 0)
            {
                LoadConstantInt load = m_info.Instructions[store.Index - 1] as LoadConstantInt;
                if (load != null)
                {
                    if (load.Value < 0 || load.Value > 255)
                    {
                        Log.DebugLine(this, "store at {0:X2}", store.Untyped.Offset);

                        if (m_stores.IndexOf(store.Variable) < 0)
                        {
                            m_stores.Add(store.Variable);
                        }
                    }
                }
            }
        }
Beispiel #5
0
        public void VisitCompare(Compare op)
        {
            // Compiler sometimes generates this code to return true.
            if (op.Index >= 2)
            {
                // ldc.i4.0
                // ldc.i4.0
                // ceq
                LoadConstantInt rhs = m_info.Instructions[op.Index - 1] as LoadConstantInt;
                LoadConstantInt lhs = m_info.Instructions[op.Index - 2] as LoadConstantInt;
                if (lhs != null && rhs != null && lhs.Value == 0 && rhs.Value == 0)
                {
                    return;
                }
            }

            if (m_offset < 0)
            {
                DoCheck(op);
            }
        }
Beispiel #6
0
            // This method is used by the Transform above and later on when we
            // need to compute the state for each instruction in a method.
            public Lattice Transform(int index)
            {
                DBC.Pre(index >= 0 && index < m_instructions.Length, "index is oor");                   // real code would probably use FastPre

                StoreLocal store = m_instructions[index] as StoreLocal;

                if (store != null)
                {
                    LoadConstantInt load = m_instructions[index - 1] as LoadConstantInt;                        // test code so we only track constant loads
                    if (load != null)
                    {
                        return(new Lattice(m_instructions, new State(load.Value)));
                    }
                    else
                    {
                        return(new Lattice(m_instructions, Indeterminate));
                    }
                }

                return(this);
            }
Beispiel #7
0
        private void DoCheckLoad(TypedInstruction instruction)
        {
            LoadConstantInt load = m_info.Instructions[instruction.Index - 1] as LoadConstantInt;

            if (load != null)
            {
                if (load.Value < 0 || load.Value > 255)
                {
                    m_offset = instruction.Untyped.Offset;
                    Log.DebugLine(this, "bad exit at {0:X2}", m_offset);
                }
            }

            LoadLocal local = m_info.Instructions[instruction.Index - 1] as LoadLocal;

            if (local != null)
            {
                Log.DebugLine(this, "{0} at {1:X2}", instruction.Untyped.OpCode, instruction.Untyped.Offset);
                if (m_candidateLoads.IndexOf(local.Variable) < 0)
                {
                    m_candidateLoads.Add(local.Variable);
                }
            }
        }
Beispiel #8
0
        public static bool IsIntOperand(MethodInfo info, int index, int nth)
        {
            bool isInt = false;

            int i = info.Tracker.GetStackIndex(index, nth);

            if (i >= 0)
            {
                do
                {
                    LoadArg arg = info.Instructions[i] as LoadArg;
                    if (arg != null && arg.Arg >= 1)
                    {
                        ParameterDefinition p = info.Method.Parameters[arg.Arg - 1];
                        if (p.ParameterType.FullName == "System.Int32")
                        {
                            isInt = true;
                        }
                        break;
                    }

                    LoadConstantInt constant = info.Instructions[i] as LoadConstantInt;
                    if (constant != null)
                    {
                        Code code = constant.Untyped.OpCode.Code;
                        switch (code)
                        {
                        case Code.Ldc_I4_M1:
                        case Code.Ldc_I4_0:
                        case Code.Ldc_I4_1:
                        case Code.Ldc_I4_2:
                        case Code.Ldc_I4_3:
                        case Code.Ldc_I4_4:
                        case Code.Ldc_I4_5:
                        case Code.Ldc_I4_6:
                        case Code.Ldc_I4_7:
                        case Code.Ldc_I4_8:
                        case Code.Ldc_I4_S:
                        case Code.Ldc_I4:
                            isInt = true;
                            break;
                        }
                        break;
                    }

                    LoadField field = info.Instructions[i] as LoadField;
                    if (field != null)
                    {
                        if (field.Field.FieldType.FullName == "System.Int32")
                        {
                            isInt = true;
                        }
                        break;
                    }

                    LoadLocal local = info.Instructions[i] as LoadLocal;
                    if (local != null)
                    {
                        VariableDefinition v = info.Method.Body.Variables[local.Variable];
                        if (v.VariableType.FullName == "System.Int32")
                        {
                            isInt = true;
                        }
                        break;
                    }

                    LoadStaticField sfield = info.Instructions[i] as LoadStaticField;
                    if (sfield != null)
                    {
                        if (sfield.Field.FieldType.FullName == "System.Int32")
                        {
                            isInt = true;
                        }
                        break;
                    }
                }while (false);
            }

            return(isInt);
        }
Beispiel #9
0
            private void DoStackPushes(List <StackEntry> stack, int index, List <StackEntry> oldStack)
            {
                long?value;

                TypedInstruction instruction = m_instructions[index];

                switch (instruction.Untyped.OpCode.Code)
                {
                case Code.Add:
                case Code.Sub:
                case Code.Mul:
                case Code.Div:
                case Code.Div_Un:
                case Code.Rem:
                case Code.Rem_Un:
                case Code.And:
                case Code.Or:
                case Code.Xor:
                case Code.Shl:
                case Code.Shr:
                case Code.Shr_Un:
                case Code.Neg:
                case Code.Not:
                case Code.Add_Ovf:
                case Code.Add_Ovf_Un:
                case Code.Mul_Ovf:
                case Code.Mul_Ovf_Un:
                case Code.Sub_Ovf:
                case Code.Sub_Ovf_Un:
                    stack.Add(new StackEntry(null, index));                                     // could compute these, but we don't care too much about integer values atm
                    break;

                case Code.Arglist:                                              // push non-null
                case Code.Box:
                case Code.Ldarga:
                case Code.Ldarga_S:
                case Code.Ldelema:
                case Code.Ldflda:
                case Code.Ldftn:
                case Code.Ldind_Ref:
                case Code.Ldloca:
                case Code.Ldloca_S:
                case Code.Ldobj:
                case Code.Ldsflda:
                case Code.Ldstr:
                case Code.Ldtoken:
                case Code.Ldvirtftn:
                case Code.Localloc:
                case Code.Mkrefany:
                case Code.Newarr:
                case Code.Newobj:
                case Code.Refanytype:
                case Code.Refanyval:
                case Code.Unbox:
                case Code.Unbox_Any:
                    stack.Add(new StackEntry(1, index));
                    break;

                case Code.Call:
                case Code.Calli:
                case Code.Callvirt:
                    Call call = instruction as Call;
                    if (call.Target.ReturnType.ReturnType.ToString() != "System.Void")
                    {
                        stack.Add(new StackEntry(null, index));
                    }
                    break;

                case Code.Castclass:
                    value = oldStack.Back().Value;
                    if (value.HasValue && value.Value == 0)
                    {
                        stack.Add(new StackEntry(0, index));
                    }
                    else
                    {
                        stack.Add(new StackEntry(1, index));
                    }
                    break;

                case Code.Ceq:                                          // push indeterminate
                case Code.Cgt:
                case Code.Cgt_Un:
                case Code.Clt:
                case Code.Clt_Un:
                case Code.Ckfinite:
                case Code.Conv_I1:
                case Code.Conv_I2:
                case Code.Conv_I4:
                case Code.Conv_I8:
                case Code.Conv_U4:
                case Code.Conv_U8:
                case Code.Conv_R4:
                case Code.Conv_R8:
                case Code.Conv_U2:
                case Code.Conv_U1:
                case Code.Conv_I:
                case Code.Conv_R_Un:
                case Code.Conv_U:
                case Code.Ldelem_I1:
                case Code.Ldelem_U1:
                case Code.Ldelem_I2:
                case Code.Ldelem_U2:
                case Code.Ldelem_I4:
                case Code.Ldelem_U4:
                case Code.Ldelem_I8:
                case Code.Ldelem_I:
                case Code.Ldelem_R4:
                case Code.Ldelem_R8:
                case Code.Ldelem_Ref:
                case Code.Ldelem_Any:
                case Code.Ldind_I1:
                case Code.Ldind_U1:
                case Code.Ldind_I2:
                case Code.Ldind_U2:
                case Code.Ldind_I4:
                case Code.Ldind_U4:
                case Code.Ldind_I8:
                case Code.Ldind_I:
                case Code.Ldind_R4:
                case Code.Ldind_R8:
                case Code.Ldfld:
                case Code.Ldsfld:
                case Code.Ldlen:
                case Code.Sizeof:
                    stack.Add(new StackEntry(null, index));
                    break;

                case Code.Conv_Ovf_I1:                                  // push previous value
                case Code.Conv_Ovf_U1:
                case Code.Conv_Ovf_I2:
                case Code.Conv_Ovf_U2:
                case Code.Conv_Ovf_I4:
                case Code.Conv_Ovf_U4:
                case Code.Conv_Ovf_I8:
                case Code.Conv_Ovf_U8:
                case Code.Conv_Ovf_I:
                case Code.Conv_Ovf_U:
                case Code.Conv_Ovf_I1_Un:
                case Code.Conv_Ovf_I2_Un:
                case Code.Conv_Ovf_I4_Un:
                case Code.Conv_Ovf_I8_Un:
                case Code.Conv_Ovf_U1_Un:
                case Code.Conv_Ovf_U2_Un:
                case Code.Conv_Ovf_U4_Un:
                case Code.Conv_Ovf_U8_Un:
                case Code.Conv_Ovf_I_Un:
                case Code.Conv_Ovf_U_Un:
                    value = oldStack.Back().Value;
                    stack.Add(new StackEntry(value, index));
                    break;

                case Code.Dup:
                    value = oldStack.Back().Value;
                    stack.Add(new StackEntry(value, index));
                    stack.Add(new StackEntry(value, index));
                    break;

                case Code.Isinst:
                    value = oldStack.Back().Value;
                    if (value.HasValue && value.Value == 0)
                    {
                        stack.Add(new StackEntry(0, index));
                    }
                    else
                    {
                        stack.Add(new StackEntry(null, index));
                    }
                    break;

                case Code.Ldarg_0:
                case Code.Ldarg_1:
                case Code.Ldarg_2:
                case Code.Ldarg_3:
                case Code.Ldarg:
                case Code.Ldarg_S:
                    LoadArg arg = instruction as LoadArg;
                    value = m_state.Arguments[arg.Arg];
                    stack.Add(new StackEntry(value, index));
                    break;

                case Code.Ldc_I4_M1:
                case Code.Ldc_I4_0:
                case Code.Ldc_I4_1:
                case Code.Ldc_I4_2:
                case Code.Ldc_I4_3:
                case Code.Ldc_I4_4:
                case Code.Ldc_I4_5:
                case Code.Ldc_I4_6:
                case Code.Ldc_I4_7:
                case Code.Ldc_I4_8:
                case Code.Ldc_I4_S:
                case Code.Ldc_I4:
                case Code.Ldc_I8:
                    LoadConstantInt constant = instruction as LoadConstantInt;
                    stack.Add(new StackEntry(constant.Value, index));
                    break;

                case Code.Ldc_R4:
                case Code.Ldc_R8:
                    LoadConstantFloat constant2 = instruction as LoadConstantFloat;
                    if (constant2.Value == 0.0)
                    {
                        stack.Add(new StackEntry(0, index));
                    }
                    else
                    {
                        stack.Add(new StackEntry(null, index));
                    }
                    break;

                case Code.Ldloc_0:
                case Code.Ldloc_1:
                case Code.Ldloc_2:
                case Code.Ldloc_3:
                case Code.Ldloc:
                case Code.Ldloc_S:
                    LoadLocal local = instruction as LoadLocal;
                    value = m_state.Locals[local.Variable];
                    stack.Add(new StackEntry(value, index));
                    break;

                case Code.Ldnull:                                                               // push null
                    stack.Add(new StackEntry(0, index));
                    break;

                default:
                    DBC.Assert(instruction.Untyped.OpCode.StackBehaviourPush == StackBehaviour.Push0, "Expected {0} to push nothing", instruction.Untyped.OpCode);
                    break;
                }
            }