示例#1
0
        public void VisitBranch(ConditionalBranch branch)
        {
            if (m_needsCheck && !m_foundSingle && branch.Index >= 2 && m_numLocks == 1)
            {
                // Look for the if within the lock:
                //    call       System.Void System.Threading.Monitor::Enter(System.Object)
                //    ldsfld     field
                //    brtrue     2A
                if (branch.Untyped.OpCode.Code == Code.Brtrue || branch.Untyped.OpCode.Code == Code.Brtrue_S)
                {
                    LoadStaticField load = m_info.Instructions[branch.Index - 1] as LoadStaticField;
                    Call            call = m_info.Instructions[branch.Index - 2] as Call;

                    if (load != null && call != null && call.Target.ToString() == "System.Void System.Threading.Monitor::Enter(System.Object)")
                    {
                        m_field = load.Field;
                        Log.DebugLine(this, "found candidate lock at {0:X2}", branch.Untyped.Offset);

                        // If we found the inner if then we need to look for a new
                        // and a store within the if,
                        if (DoFindNew(branch.Index + 1, branch.Target.Index - branch.Index - 1))
                        {
                            m_foundSingle = true;

                            // and a second guard before the lock.
                            if (DoFindGuard(call.Index - 1))
                            {
                                m_foundGuard = true;
                            }
                        }
                    }
                }
            }
        }
示例#2
0
        private bool DoIsEmptyString(Call call, int nth)
        {
            bool empty = false;

            int index = m_info.Tracker.GetStackIndex(call.Index, nth);

            if (index >= 0)
            {
                LoadString str = m_info.Instructions[index] as LoadString;
                if (str != null)
                {
                    empty = str.Value.Length == 0;
                }
                else
                {
                    LoadStaticField field = m_info.Instructions[index] as LoadStaticField;
                    if (field != null)
                    {
                        empty = field.Field.DeclaringType.FullName == "System.String" && field.Field.Name == "Empty";
                    }
                }
            }

            return(empty);
        }
示例#3
0
        private TypeReference DoGetType(int index, int nth)
        {
            TypeReference type = null;

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

            if (i >= 0)
            {
                do                      // TODO: would be nice to do something with load constant instructions as well
                {
                    LoadArg arg = m_info.Instructions[i] as LoadArg;
                    if (arg != null && arg.Arg >= 1)
                    {
                        ParameterDefinition p = m_info.Method.Parameters[arg.Arg - 1];
                        type = p.ParameterType;
                        break;
                    }

                    LoadField field = m_info.Instructions[i] as LoadField;
                    if (field != null)
                    {
                        type = field.Field.FieldType;
                        break;
                    }

                    LoadLocal local = m_info.Instructions[i] as LoadLocal;
                    if (local != null)
                    {
                        VariableDefinition v = m_info.Method.Body.Variables[local.Variable];
                        type = v.VariableType;
                        break;
                    }

                    LoadStaticField sfield = m_info.Instructions[i] as LoadStaticField;
                    if (sfield != null)
                    {
                        type = sfield.Field.FieldType;
                        break;
                    }

                    Box box = m_info.Instructions[i] as Box;
                    if (box != null)
                    {
                        type = box.Type;
                        break;
                    }
                }while (false);
            }

            return(type);
        }
示例#4
0
 // match:
 //      ldsfld     field
 //      ret
 public void VisitRet(End end)
 {
     if (m_needsCheck && !m_foundRet && m_foundSingle)
     {
         if (end.Untyped.OpCode.Code == Code.Ret && end.Index > 1)
         {
             LoadStaticField load = m_info.Instructions[end.Index - 1] as LoadStaticField;
             if (load != null && load.Field == m_field)
             {
                 Log.DebugLine(this, "found return at {0:X2}", end.Untyped.Offset);
                 m_foundRet = true;
             }
         }
     }
 }
示例#5
0
        public void VisitCall(Call call)
        {
            if (m_fields.Count > 0 && !m_info.Method.IsConstructor && call.Target.HasThis)
            {
                int index = call.GetThisIndex(m_info);

                if (index >= 0)
                {
                    LoadStaticField load = m_info.Instructions[index] as LoadStaticField;

                    if (load != null && m_fields.IndexOf(load.Field) >= 0)
                    {
                        Entry entry = m_table[load.Field];

                        if (m_adders[entry.Key].IndexOf(call.Target.Name) >= 0)
                        {
                            if (!DoIsNullSet(call.Index, call.Target.Name))
                            {
                                if (!entry.FoundAdd)
                                {
                                    Log.DebugLine(this, "found an add at {0:X2}", call.Untyped.Offset);
                                    entry.FoundAdd = true;
                                }
                            }
                            else
                            {
                                if (!entry.FoundRemove)
                                {
                                    Log.DebugLine(this, "found a null set at {0:X2}", call.Untyped.Offset);
                                    entry.FoundRemove = true;
                                }
                            }
                        }

                        if (!entry.FoundRemove)
                        {
                            if (m_removers[entry.Key].IndexOf(call.Target.Name) >= 0)
                            {
                                Log.DebugLine(this, "found a remove at {0:X2}", call.Untyped.Offset);
                                entry.FoundRemove = true;
                            }
                        }
                    }
                }
            }
        }
示例#6
0
        private TypeReference DoGetThisType(Call call)
        {
            TypeReference self = null;

            if (call.Target.HasThis)
            {
                int index = call.GetThisIndex(m_info);

                if (index >= 0)
                {
                    do
                    {
                        LoadArg arg = m_info.Instructions[index] as LoadArg;
                        if (arg != null)
                        {
                            self = arg.Type;
                            break;
                        }

                        LoadField field = m_info.Instructions[index] as LoadField;
                        if (field != null)
                        {
                            self = field.Field.FieldType;
                            break;
                        }

                        LoadStaticField sfield = m_info.Instructions[index] as LoadStaticField;
                        if (sfield != null)
                        {
                            self = sfield.Field.FieldType;
                            break;
                        }

                        LoadLocal local = m_info.Instructions[index] as LoadLocal;
                        if (local != null)
                        {
                            self = local.Type;
                            break;
                        }
                    }while (false);
                }
            }

            return(self);
        }
示例#7
0
 public void VisitLoadStaticField(LoadStaticField load)
 {
     if (m_needsCheck)
     {
         State state;
         if (m_fields.TryGetValue(load.Field, out state))
         {
             if (state == State.Defined)
             {
                 m_fields[load.Field] = State.Used;
             }
         }
         else
         {
             m_fields.Add(load.Field, State.Referenced);
         }
     }
 }
示例#8
0
        // Find the following working backwards from index:
        //      ldsfld     field
        //      brtrue     36
        private bool DoFindGuard(int index)
        {
            while (index > 0)
            {
                ConditionalBranch branch = m_info.Instructions[index] as ConditionalBranch;
                if (branch != null && (branch.Untyped.OpCode.Code == Code.Brtrue || branch.Untyped.OpCode.Code == Code.Brtrue_S))
                {
                    LoadStaticField load = m_info.Instructions[index - 1] as LoadStaticField;
                    if (load != null && load.Field == m_field)
                    {
                        Log.DebugLine(this, "found the guard at {0:X2}", branch.Untyped.Offset);
                        return(true);
                    }
                }
                --index;
            }

            return(false);
        }
示例#9
0
        private FieldReference DoSaveLocks(Call call)
        {
            FieldReference field = null;

            // Look for a lock using one of our fields.
            if (DoMatchLock1(call.Index))
            {
                LoadStaticField sload = (LoadStaticField)m_info.Instructions[call.Index - 3];
                if (sload.Field.DeclaringType == m_info.Type)
                {
                    field = sload.Field;
                }
            }
            else if (DoMatchLock2(call.Index))
            {
                LoadField load = (LoadField)m_info.Instructions[call.Index - 3];
                field = load.Field;
            }

            // If we found one then record that the method locked the field.
            if (field != null)
            {
                List <FieldReference> fields;

                if (!m_current.Locked.TryGetValue(m_info.Method, out fields))
                {
                    fields = new List <FieldReference>();
                    m_current.Locked.Add(m_info.Method, fields);
                }

                fields.Add(field);
                Log.DebugLine(this, "{0} locks {1}", m_info.Method.Name, field.Name);
            }

            return(field);
        }
示例#10
0
 public void VisitSLoadField(LoadStaticField load)
 {
     DoAddField(load.Field);
 }
示例#11
0
 public void VisitLoadStaticField(LoadStaticField field)
 {
     DoAdd(field.Field.FieldType);
 }
示例#12
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);
        }
示例#13
0
        private bool DoIsFloat(int index)
        {
            TypedInstruction instruction = m_info.Instructions[index];
            TypeReference    type        = null;

            do
            {
                LoadArg arg = instruction as LoadArg;
                if (arg != null && arg.Arg >= 1)
                {
                    type = m_info.Method.Parameters[arg.Arg - 1].ParameterType;
                    break;
                }

                LoadLocal local = instruction as LoadLocal;
                if (local != null)
                {
                    type = m_info.Method.Body.Variables[local.Variable].VariableType;
                    break;
                }

                LoadField field = instruction as LoadField;
                if (field != null)
                {
                    type = field.Field.FieldType;
                    break;
                }

                LoadStaticField sfield = instruction as LoadStaticField;
                if (sfield != null)
                {
                    type = sfield.Field.FieldType;
                    break;
                }

                LoadConstantFloat cf = instruction as LoadConstantFloat;
                if (cf != null)
                {
                    return(cf.Value != double.PositiveInfinity && cf.Value != double.NegativeInfinity);
                }

                BinaryOp binary = instruction as BinaryOp;
                if (binary != null)
                {
                    int j = m_info.Tracker.GetStackIndex(instruction.Index, 0);
                    int k = m_info.Tracker.GetStackIndex(instruction.Index, 1);

                    if (j >= 0 && k >= 0)
                    {
                        if (DoIsFloat(j) && DoIsFloat(k))
                        {
                            return(true);
                        }
                    }
                }

                if (instruction.Untyped.OpCode.Code == Code.Conv_R4 || instruction.Untyped.OpCode.Code == Code.Conv_R8 || instruction.Untyped.OpCode.Code == Code.Conv_R_Un)
                {
                    return(true);
                }

                Call call = instruction as Call;
                if (call != null)
                {
                    type = call.Target.ReturnType.ReturnType;
                    break;
                }
            }while (false);

            return(type != null && (type.FullName == "System.Single" || type.FullName == "System.Double"));
        }
示例#14
0
        private bool DoIsBad(int index)
        {
            bool bad = false;

            do
            {
                LoadArg arg = m_info.Instructions[index] as LoadArg;
                if (arg != null && arg.Arg >= 1)
                {
                    Log.DebugLine(this, "arg: {0}", arg.Arg);

                    ParameterDefinition p = m_info.Method.Parameters[arg.Arg - 1];
                    Log.DebugLine(this, "param {0} is of type {1}", arg.Arg, p.ParameterType.FullName);
                    if (DoIsBad(p.ParameterType))
                    {
                        bad = true;
                    }
                    break;
                }

                LoadLocal local = m_info.Instructions[index] as LoadLocal;
                if (local != null)
                {
                    Log.DebugLine(this, "local: {0}", local.Variable);

                    TypeReference type = m_info.Method.Body.Variables[local.Variable].VariableType;
                    Log.DebugLine(this, "local {0} is of type {1}", local.Variable, type.FullName);
                    if (DoIsBad(type))
                    {
                        bad = true;
                    }
                    break;
                }

                LoadField field = m_info.Instructions[index] as LoadField;
                if (field != null)
                {
                    Log.DebugLine(this, "field: {0}", field.Field.Name);

                    TypeReference type = field.Field.FieldType;
                    Log.DebugLine(this, "field {0} is of type {1}", field.Field.Name, type.FullName);
                    if (DoIsBad(type))
                    {
                        bad = true;
                    }
                    break;
                }

                LoadStaticField sfield = m_info.Instructions[index] as LoadStaticField;
                if (sfield != null)
                {
                    Log.DebugLine(this, "static field: {0}", sfield.Field.Name);

                    TypeReference type = sfield.Field.FieldType;
                    Log.DebugLine(this, "static field {0} is of type {1}", sfield.Field.Name, type.FullName);
                    if (DoIsBad(type))
                    {
                        bad = true;
                    }
                    break;
                }
            }while (false);

            return(bad);
        }