Пример #1
0
 public void VisitInstruction(TypedInstruction instruction)
 {
     if (m_offset < 0)
     {
         m_offset = NullCheck.Check <NullDerefRule>(instruction, m_info.Tracker, out m_details);
     }
 }
Пример #2
0
        // 02: call       System.Int32 System.Array::IndexOf<*>(!!0[],!!0)
        // 07: stloc.N    V_0
        // 08: ldc.i4.0
        // 09: ldloc.N    V_0
        // 0A: bge        1E
        private bool DoMatch3(int index)
        {
            bool match = false;

            do
            {
                if (index - 4 < 0)
                {
                    break;
                }

                TypedInstruction instruction = m_info.Instructions[index - 0];
                Code             code        = instruction.Untyped.OpCode.Code;
                if (code != Code.Bge_S && code != Code.Bge_Un_S && code != Code.Bge && code != Code.Bge_Un)
                {
                    break;
                }

                instruction = m_info.Instructions[index - 1];
                code        = instruction.Untyped.OpCode.Code;
                if (code != Code.Ldloc_S && code != Code.Ldloc && code != Code.Ldloc_0 && code != Code.Ldloc_1 && code != Code.Ldloc_2 && code != Code.Ldloc_3)
                {
                    break;
                }
                int varN = ((LoadLocal)instruction).Variable;

                instruction = m_info.Instructions[index - 2];
                code        = instruction.Untyped.OpCode.Code;
                if (code != Code.Ldc_I4_0)
                {
                    break;
                }

                instruction = m_info.Instructions[index - 3];
                code        = instruction.Untyped.OpCode.Code;
                if (code != Code.Stloc_S && code != Code.Stloc && code != Code.Stloc_0 && code != Code.Stloc_1 && code != Code.Stloc_2 && code != Code.Stloc_3)
                {
                    break;
                }
                if (varN != ((StoreLocal)instruction).Variable)
                {
                    break;
                }

                instruction = m_info.Instructions[index - 4];
                code        = instruction.Untyped.OpCode.Code;
                if (code != Code.Call && code != Code.Callvirt)
                {
                    break;
                }
                if (!((Call)instruction).Target.ToString().StartsWith("System.Int32 System.Array::IndexOf<") || !((Call)instruction).Target.ToString().EndsWith(">(!!0[],!!0)"))
                {
                    break;
                }

                match = true;
            }while (false);

            return(match);
        }
Пример #3
0
        private void DoCheck(TypedInstruction binary)
        {
            if (binary.Index >= 2)
            {
                int rhsEnd   = binary.Index - 1;
                int rhsStart = rhsEnd - DoGetPushRange(m_info, rhsEnd);

                int lhsEnd   = rhsStart - 1;
                int lhsStart = lhsEnd - DoGetPushRange(m_info, lhsEnd);

                Log.DebugLine(this, "{0} at {1:X}", binary.Untyped.OpCode.Code, binary.Untyped.Offset);
                Log.DebugLine(this, "   lhs range: [{0:X}, {1:X}]", m_info.Instructions[lhsStart].Untyped.Offset, m_info.Instructions[lhsEnd].Untyped.Offset);
                Log.DebugLine(this, "   rhs range: [{0:X}, {1:X}]", m_info.Instructions[rhsStart].Untyped.Offset, m_info.Instructions[rhsEnd].Untyped.Offset);

                bool matches = (rhsEnd - rhsStart) == (lhsEnd - lhsStart);
                for (int i = 0; i <= (rhsEnd - rhsStart) && matches; ++i)
                {
                    TypedInstruction lhs = m_info.Instructions[lhsStart + i];
                    TypedInstruction rhs = m_info.Instructions[rhsStart + i];

                    matches = lhs.Untyped.Matches(rhs.Untyped);
                }

                if (matches)
                {
                    m_offset = binary.Untyped.Offset;
                }
            }
        }
Пример #4
0
        [DisableRule("D1042", "IdenticalMethods")]                      // TODO: matches RecursiveLock2Rule
        private bool DoMatchLock2(int index)
        {
            bool match = false;

            do
            {
                if (index - 4 < 0 || index >= m_info.Instructions.Length)
                {
                    break;
                }

                TypedInstruction instruction = m_info.Instructions[index - 0];
                Code             code        = instruction.Untyped.OpCode.Code;
                if (code != Code.Call && code != Code.Callvirt)
                {
                    break;
                }
                if (((Call)instruction).Target.ToString() != "System.Void System.Threading.Monitor::Enter(System.Object)")
                {
                    break;
                }

                instruction = m_info.Instructions[index - 1];
                code        = instruction.Untyped.OpCode.Code;
                if (code != Code.Ldloc_S && code != Code.Ldloc && code != Code.Ldloc_0 && code != Code.Ldloc_1 && code != Code.Ldloc_2 && code != Code.Ldloc_3)
                {
                    break;
                }
                int varN = ((LoadLocal)instruction).Variable;

                instruction = m_info.Instructions[index - 2];
                code        = instruction.Untyped.OpCode.Code;
                if (code != Code.Stloc_S && code != Code.Stloc && code != Code.Stloc_0 && code != Code.Stloc_1 && code != Code.Stloc_2 && code != Code.Stloc_3)
                {
                    break;
                }
                if (varN != ((StoreLocal)instruction).Variable)
                {
                    break;
                }

                instruction = m_info.Instructions[index - 3];
                code        = instruction.Untyped.OpCode.Code;
                if (code != Code.Ldfld)
                {
                    break;
                }

                instruction = m_info.Instructions[index - 4];
                code        = instruction.Untyped.OpCode.Code;
                if (code != Code.Ldarg_0)
                {
                    break;
                }

                match = true;
            }while (false);

            return(match);
        }
Пример #5
0
 public void VisitInstruction(TypedInstruction instruction)
 {
     if (m_needsCheck && !m_foundEarlyReturn && m_offset < 0)
     {
         m_offset = NullCheck.Check <EqualsRequiresNullCheckRule>(instruction, m_tracker, out m_details);
     }
 }
Пример #6
0
        // 03: callvirt   System.Int32 System.String::IndexOf(System.Char)
        // 08: stloc.N    V_0
        // 09: ldc.i4.0
        // 0A: ldloc.N    V_0
        // 0B: bge        1F
        private bool DoMatch5(int index)
        {
            bool match = false;

            do
            {
                if (index - 4 < 0)
                {
                    break;
                }

                TypedInstruction instruction = m_info.Instructions[index - 0];
                Code             code        = instruction.Untyped.OpCode.Code;
                if (code != Code.Bge_S && code != Code.Bge_Un_S && code != Code.Bge && code != Code.Bge_Un)
                {
                    break;
                }

                instruction = m_info.Instructions[index - 1];
                code        = instruction.Untyped.OpCode.Code;
                if (code != Code.Ldloc_S && code != Code.Ldloc && code != Code.Ldloc_0 && code != Code.Ldloc_1 && code != Code.Ldloc_2 && code != Code.Ldloc_3)
                {
                    break;
                }
                int varN = ((LoadLocal)instruction).Variable;

                instruction = m_info.Instructions[index - 2];
                code        = instruction.Untyped.OpCode.Code;
                if (code != Code.Ldc_I4_0)
                {
                    break;
                }

                instruction = m_info.Instructions[index - 3];
                code        = instruction.Untyped.OpCode.Code;
                if (code != Code.Stloc_S && code != Code.Stloc && code != Code.Stloc_0 && code != Code.Stloc_1 && code != Code.Stloc_2 && code != Code.Stloc_3)
                {
                    break;
                }
                if (varN != ((StoreLocal)instruction).Variable)
                {
                    break;
                }

                instruction = m_info.Instructions[index - 4];
                code        = instruction.Untyped.OpCode.Code;
                if (code != Code.Callvirt && code != Code.Call)
                {
                    break;
                }
                if (((Call)instruction).Target.ToString() != "System.Int32 System.String::IndexOf(System.Char)")
                {
                    break;
                }

                match = true;
            }while (false);

            return(match);
        }
Пример #7
0
        // 0E: br         27
        // 13: ldsfld     System.Object Smokey.Tests.UnusualMonitor1Test/Good5::m_lock
        // 18: call       System.Boolean System.Threading.Monitor::Wait(System.Object)
        // 1D: box        System.Boolean
        // 22: call       System.Void Smokey.Internal.Ignore::set_Value(System.Object)
        private bool DoMatch2a(int index)
        {
            bool match = false;

            do
            {
                if (index - 4 < 0 || index >= m_info.Instructions.Length)
                {
                    break;
                }

                TypedInstruction instruction = m_info.Instructions[index - 0];
                Code             code        = instruction.Untyped.OpCode.Code;
                if (code != Code.Call && code != Code.Callvirt)
                {
                    break;
                }
                if (((Call)instruction).Target.ToString().IndexOf("Ignore::set_Value") < 0 && ((Call)instruction).Target.ToString().IndexOf("Unused::set_Value") < 0)
                {
                    break;
                }

                instruction = m_info.Instructions[index - 1];
                code        = instruction.Untyped.OpCode.Code;
                if (code != Code.Box)
                {
                    break;
                }

                instruction = m_info.Instructions[index - 2];
                code        = instruction.Untyped.OpCode.Code;
                if (code != Code.Call && code != Code.Callvirt)
                {
                    break;
                }
                if (((Call)instruction).Target.ToString() != "System.Boolean System.Threading.Monitor::Wait(System.Object)")
                {
                    break;
                }

                instruction = m_info.Instructions[index - 3];
                code        = instruction.Untyped.OpCode.Code;
                if (code != Code.Ldsfld)
                {
                    break;
                }

                instruction = m_info.Instructions[index - 4];
                code        = instruction.Untyped.OpCode.Code;
                if (code != Code.Br_S && code != Code.Br)
                {
                    break;
                }

                match = true;
            }while (false);

            return(match);
        }
Пример #8
0
        private List <int> DoGetLeaders(TypedInstructionCollection instructions)
        {
            // The leaders will be:
            List <int> leaders = new List <int>();

            // 1) the first instruction in the method,
            leaders.Add(0);

            for (int index = 0; index < instructions.Length; ++index)
            {
                TypedInstruction instruction = instructions[index];

                // 2) the targets of branches,
                Branch branch = instruction as Branch;
                if (branch != null)
                {
                    m_branchTargets.Add(branch.Target.Index);
                }
                else
                {
                    Switch swtch = instruction as Switch;
                    if (swtch != null)
                    {
                        foreach (TypedInstruction i in swtch.Targets)
                        {
                            m_branchTargets.Add(i.Index);
                        }
                    }
                }

                if (index > 0)
                {
                    // 3) and instructions starting try, catch or finally blocks,
                    TryCatch tc = instructions.TryCatchCollection.HandlerStartsAt(index);
                    if (tc != null)
                    {
                        leaders.Add(index);
                    }

                    // 4) the instructions following branches or end instructions.
                    else if (instructions[index - 1] is Branch || instructions[index - 1] is Switch || instructions[index - 1] is End)
                    {
                        leaders.Add(index);
                    }
                }
            }

            foreach (int target in m_branchTargets)
            {
                if (leaders.IndexOf(target) < 0)
                {
                    leaders.Add(target);
                }
            }

            return(leaders);
        }
Пример #9
0
        private int DoGetStackDelta(TypedInstruction instruction)
        {
            int delta = 0;

            delta += DoGetStackCount(instruction, instruction.Untyped.OpCode.StackBehaviourPush);
            delta -= DoGetStackCount(instruction, instruction.Untyped.OpCode.StackBehaviourPop);
//			Log.DebugLine(this, "{0} (delta = {1})", instruction, delta);

            return(delta);
        }
Пример #10
0
 public void VisitNew(NewObj obj)
 {
     if (m_offset < 0 && obj.Index + 1 < m_info.Instructions.Length)
     {
         TypedInstruction prev = m_info.Instructions[obj.Index + 1];
         if (prev.Untyped.OpCode.Code == Code.Pop)
         {
             m_offset = obj.Untyped.Offset;
             Log.DebugLine(this, "Matched at {0:X2}", m_offset);
         }
     }
 }
Пример #11
0
            private static void DoSpliceEq(TypedInstructionCollection instructions, BasicBlock block)
            {
                int index = block.Last.Index;

                // ldloc.0 V_0
                // ldnull
                // beq     2F
                LoadArg   arg   = null;
                LoadLocal local = null;

                if (instructions[index - 1].Untyped.OpCode.Code == Code.Ldnull)
                {
                    arg   = instructions[block.Last.Index - 2] as LoadArg;
                    local = instructions[block.Last.Index - 2] as LoadLocal;
                }
                else if (instructions[index - 2].Untyped.OpCode.Code == Code.Ldnull)
                {
                    arg   = instructions[block.Last.Index - 1] as LoadArg;
                    local = instructions[block.Last.Index - 1] as LoadLocal;
                }

                if (arg != null || local != null)
                {
                    TypedInstruction instruction = instructions[block.Last.Index];
                    Code             code        = instruction.Untyped.OpCode.Code;

                    if (code == Code.Bne_Un || code == Code.Bne_Un_S)
                    {
                        if (arg != null)
                        {
                            DoSpliceNull(block, FirstNullArgBlockLen - arg.Arg, FirstNonNullArgBlockLen - arg.Arg);
                        }

                        else
                        {
                            DoSpliceNull(block, FirstNullLocalBlockLen - local.Variable, FirstNonNullLocalBlockLen - local.Variable);
                        }
                    }
                    else
                    {
                        if (arg != null)
                        {
                            DoSpliceNull(block, FirstNonNullArgBlockLen - arg.Arg, FirstNullArgBlockLen - arg.Arg);
                        }

                        else
                        {
                            DoSpliceNull(block, FirstNonNullLocalBlockLen - local.Variable, FirstNullLocalBlockLen - local.Variable);
                        }
                    }
                }
            }
Пример #12
0
            private static void DoTrySpliceNull(TypedInstructionCollection instructions, BasicBlock block)
            {
                TypedInstruction instruction = instructions[block.Last.Index];
                Code             code        = instruction.Untyped.OpCode.Code;

                if (code == Code.Brtrue || code == Code.Brtrue_S || code == Code.Brfalse || code == Code.Brfalse_S)
                {
                    DoSpliceTrue(instructions, block);
                }
                else if (code == Code.Beq || code == Code.Beq_S || code == Code.Bne_Un || code == Code.Bne_Un_S)
                {
                    DoSpliceEq(instructions, block);
                }
            }
Пример #13
0
        private void DoCheck(TypedInstruction call, MethodReference target, int nth)
        {
            int index = m_info.Tracker.GetStackIndex(call.Index, nth);

            if (index >= 0)
            {
                LoadString load = m_info.Instructions[index] as LoadString;
                if (load != null)
                {
                    m_offset = call.Untyped.Offset;
                    m_bad    = target.ToString();
                    Log.DebugLine(this, "bad call at {0:X2}", m_offset);
                }
            }
        }
Пример #14
0
        // 08: switch     26 35 53 44 44 44
        // 21: br         53
        // 26: ldstr      "zero"
        // 2B: call       System.Void System.Console::WriteLine(System.String)
        // 30: br         53
        // 35: ldstr      "zero"
        // 3A: call       System.Void System.Console::WriteLine(System.String)
        // 3F: br         53
        // 44: ldstr      "zero"
        // 49: call       System.Void System.Console::WriteLine(System.String)
        // 4E: br         53
        // 53: ret
        public void VisitSwitch(Switch swtch)
        {
            if (m_offset < 0)
            {
                UnconditionalBranch unconditional = m_info.Instructions[swtch.Index + 1] as UnconditionalBranch;
                if (unconditional != null && unconditional.Target.Index > unconditional.Index)
                {
                    TypedInstruction last = unconditional.Target;

                    List <TypedInstruction> cases = new List <TypedInstruction>();
                    foreach (TypedInstruction ti in swtch.Targets)
                    {
                        if (ti.Index != last.Index)
                        {
                            if (cases.IndexOf(ti) < 0)
                            {
                                cases.Add(ti);
                            }
                        }
                    }
                    cases.Add(last);

                    cases.Sort((lhs, rhs) => lhs.Index.CompareTo(rhs.Index));

                    for (int i = 0; i < cases.Count - 1 && m_offset < 0; ++i)
                    {
                        TypedInstruction ti1 = cases[i];
                        int len1             = cases[i + 1].Index - ti1.Index - 1;

                        for (int j = i + 1; j < cases.Count - 1 && m_offset < 0; ++j)
                        {
                            TypedInstruction ti2 = cases[j];
                            int len2             = cases[j + 1].Index - ti2.Index - 1;
                            if (len1 == len2)
                            {
                                if (DoMatches(ti1.Index, ti2.Index, len1))
                                {
                                    Log.DebugLine(this, "{0:X2} matches {1:X2}", ti1.Untyped.Offset, ti2.Untyped.Offset);
                                    m_offset = swtch.Untyped.Offset;
                                }
                            }
                        }
                    }
                }
            }
        }
Пример #15
0
        private bool DoMatch(MethodCapture lhs, MethodCapture rhs)
        {
            if (lhs.Method.ReturnType.MetadataToken != rhs.Method.ReturnType.MetadataToken)
            {
                Log.DebugLine(this, "   return type differs");
                return(false);
            }

            if (lhs.Method.Parameters.Count != rhs.Method.Parameters.Count)
            {
                Log.DebugLine(this, "   numParams differs");
                return(false);
            }

            for (int i = 0; i < lhs.Method.Parameters.Count; ++i)
            {
                if (lhs.Method.Parameters[i].ParameterType.MetadataToken != rhs.Method.Parameters[i].ParameterType.MetadataToken)
                {
                    Log.DebugLine(this, "   param types differ");
                    return(false);
                }
            }


            if (lhs.Instructions.Length != rhs.Instructions.Length)
            {
                Log.DebugLine(this, "   numInstructions differs");
                return(false);
            }

            for (int i = 0; i < lhs.Instructions.Length; ++i)
            {
                TypedInstruction left  = lhs.Instructions[i];
                TypedInstruction right = rhs.Instructions[i];

                if (!DoMatch(left, right))
                {
                    Log.DebugLine(this, "   {0} != {1} at {2:X2} and {3:X2}", left, right, left.Untyped.Offset, right.Untyped.Offset);
                    return(false);
                }
            }

            return(true);
        }
Пример #16
0
        private static string DoTargetsToString(TypedInstructionCollection instructions, List <int> targets)
        {
            StringBuilder builder = new StringBuilder();

            builder.Append('[');
            for (int i = 0; i < targets.Count; ++i)
            {
                int index = targets[i];
                TypedInstruction instruction = instructions[index];

                builder.Append(instruction.Untyped.Offset.ToString("X2"));
                if (i + 1 < targets.Count)
                {
                    builder.Append(", ");
                }
            }
            builder.Append(']');

            return(builder.ToString());
        }
Пример #17
0
        // 02: call       System.Int32 System.Array::IndexOf<*>(!!0[],!!0)
        // 09: ldc.i4.0
        // 0A: cgt
        private bool DoMatch2b(int index)
        {
            bool match = false;

            do
            {
                if (index - 2 < 0)
                {
                    break;
                }

                TypedInstruction instruction = m_info.Instructions[index - 0];
                Code             code        = instruction.Untyped.OpCode.Code;
                if (code != Code.Cgt && code != Code.Cgt_Un)
                {
                    break;
                }

                instruction = m_info.Instructions[index - 1];
                code        = instruction.Untyped.OpCode.Code;
                if (code != Code.Ldc_I4_0)
                {
                    break;
                }

                instruction = m_info.Instructions[index - 2];
                code        = instruction.Untyped.OpCode.Code;
                if (code != Code.Call && code != Code.Callvirt)
                {
                    break;
                }
                if (!((Call)instruction).Target.ToString().StartsWith("System.Int32 System.Array::IndexOf<") || !((Call)instruction).Target.ToString().EndsWith(">(!!0[],!!0)"))
                {
                    break;
                }

                match = true;
            }while (false);

            return(match);
        }
Пример #18
0
        // 03: callvirt   System.Int32 System.String::IndexOf(System.Char)
        // 0A: ldc.i4.0
        // 0B: cgt
        private bool DoMatch4b(int index)
        {
            bool match = false;

            do
            {
                if (index - 2 < 0)
                {
                    break;
                }

                TypedInstruction instruction = m_info.Instructions[index - 0];
                Code             code        = instruction.Untyped.OpCode.Code;
                if (code != Code.Cgt && code != Code.Cgt_Un)
                {
                    break;
                }

                instruction = m_info.Instructions[index - 1];
                code        = instruction.Untyped.OpCode.Code;
                if (code != Code.Ldc_I4_0)
                {
                    break;
                }

                instruction = m_info.Instructions[index - 2];
                code        = instruction.Untyped.OpCode.Code;
                if (code != Code.Callvirt && code != Code.Call)
                {
                    break;
                }
                if (((Call)instruction).Target.ToString() != "System.Int32 System.String::IndexOf(System.Char)")
                {
                    break;
                }

                match = true;
            }while (false);

            return(match);
        }
Пример #19
0
            private static void DoSpliceTrue(TypedInstructionCollection instructions, BasicBlock block)
            {
                int index = block.Last.Index;

                // ldarg.1 a1
                // brtrue  10	(not taken is the first branch)
                LoadArg   arg   = instructions[index - 1] as LoadArg;
                LoadLocal local = instructions[index - 1] as LoadLocal;

                if (arg != null || local != null)
                {
                    TypedInstruction instruction = instructions[index];
                    Code             code        = instruction.Untyped.OpCode.Code;

                    if (code == Code.Brtrue || code == Code.Brtrue_S)
                    {
                        if (arg != null)
                        {
                            DoSpliceNull(block, FirstNullArgBlockLen - arg.Arg, FirstNonNullArgBlockLen - arg.Arg);
                        }

                        else
                        {
                            DoSpliceNull(block, FirstNullLocalBlockLen - local.Variable, FirstNonNullLocalBlockLen - local.Variable);
                        }
                    }
                    else
                    {
                        if (arg != null)
                        {
                            DoSpliceNull(block, FirstNonNullArgBlockLen - arg.Arg, FirstNullArgBlockLen - arg.Arg);
                        }

                        else
                        {
                            DoSpliceNull(block, FirstNonNullLocalBlockLen - local.Variable, FirstNullLocalBlockLen - local.Variable);
                        }
                    }
                }
            }
Пример #20
0
        private int DoCheckCatch(TypedInstructionCollection instructions, CatchBlock cb, int varIndex)
        {
            int offset = -1;

            // Loop through all of the instructions in the catch block,
            for (int index = cb.Index; index < cb.Index + cb.Length && offset < 0; ++index)
            {
                TypedInstruction instruction = instructions[index];

                // if we find a throw instruction,
                if (instruction.Untyped.OpCode.Code == Code.Throw)
                {
                    // and it's preceded by a load from varIndex then we have a problem.
                    LoadLocal load = instructions[index - 1] as LoadLocal;
                    if (load != null && load.Variable == varIndex)
                    {
                        offset = instruction.Untyped.Offset;
                        Log.DebugLine(this, "bad throw at {0:X2}", offset);
                    }
                }
            }

            return(offset);
        }
Пример #21
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);
                }
            }
        }
Пример #22
0
        private bool DoMatch(TypedInstruction lhs, TypedInstruction rhs)
        {
            if (lhs.Untyped.OpCode.Code != rhs.Untyped.OpCode.Code)
            {
                return(false);
            }

            if (lhs.Untyped.Operand != null || rhs.Untyped.Operand != null)
            {
                if (lhs.Untyped.Operand != null && rhs.Untyped.Operand != null)
                {
                    if (!DoMatchOperand(lhs.Untyped.Operand, rhs.Untyped.Operand))
                    {
                        return(false);
                    }
                }
                else
                {
                    return(false);
                }
            }

            return(true);
        }
Пример #23
0
        private bool DoMatch(CodeBlock lhs, CodeBlock rhs, int count)
        {
            Log.DebugLine(this, "   lhs: {0} at {1:X2}", lhs.Method, lhs.Instructions[lhs.Index].Untyped.Offset);
            Log.DebugLine(this, "   rhs: {0} at {1:X2}", rhs.Method, rhs.Instructions[rhs.Index].Untyped.Offset);
            Log.DebugLine(this, "   count: {0}", count);

            for (int i = 0; i < count; ++i)
            {
                TypedInstruction left  = lhs.Instructions[lhs.Index + i];
                TypedInstruction right = rhs.Instructions[rhs.Index + i];

                LoadLocal        load1  = left as LoadLocal;
                LoadLocal        load2  = right as LoadLocal;
                LoadLocalAddress load1b = left as LoadLocalAddress;
                LoadLocalAddress load2b = right as LoadLocalAddress;
                StoreLocal       store1 = left as StoreLocal;
                StoreLocal       store2 = right as StoreLocal;

                if (load1 != null && load2 != null)
                {
                    // If we have real names for the local variables (from the mdb file) then
                    // life is good and we can compare the names. If not we're stuck: we can't
                    // simply use the variable index because we'll get false positives.
                    if (!load1.RealName)
                    {
                        Log.DebugLine(this, "   can't match local name");
                        return(false);
                    }
                    // This should be a temporary in which case we can't use the variable index.
                    else if (load1.Name.StartsWith("V_") && load1.Type.FullName != load2.Type.FullName)
                    {
                        Log.DebugLine(this, "   {0} != {1} ({2} and {3})", left, right, load1.Type.FullName, load2.Type.FullName);
                        return(false);
                    }
                    else if (!load1.Name.StartsWith("V_") && load1.Name != load2.Name)
                    {
                        Log.DebugLine(this, "   {0} != {1} ({2} and {3})", left, right, load1.Name, load2.Name);
                        return(false);
                    }
                }
                else if (load1b != null && load2b != null)
                {
                    if (!load1b.RealName)
                    {
                        Log.DebugLine(this, "   can't match local name");
                        return(false);
                    }
                    else if (load1b.Name.StartsWith("V_") && load1b.Type.FullName != load2b.Type.FullName)
                    {
                        Log.DebugLine(this, "   {0} != {1} ({2} and {3})", left, right, load1b.Type.FullName, load2b.Type.FullName);
                        return(false);
                    }
                    else if (!load1b.Name.StartsWith("V_") && load1b.Name != load2b.Name)
                    {
                        Log.DebugLine(this, "   {0} != {1} ({2} and {3})", left, right, load1b.Name, load2b.Name);
                        return(false);
                    }
                }
                else if (store1 != null && store2 != null)
                {
                    if (!store1.RealName)
                    {
                        Log.DebugLine(this, "   can't match local name");
                        return(false);
                    }
                    else if (store1.Name.StartsWith("V_") && store1.Type.FullName != store2.Type.FullName)
                    {
                        Log.DebugLine(this, "   {0} != {1} ({2} and {3})", left, right, store1.Type.FullName, store2.Type.FullName);
                        return(false);
                    }
                    else if (!store1.Name.StartsWith("V_") && store1.Name != store2.Name)
                    {
                        Log.DebugLine(this, "   {0} != {1} ({2} and {3})", left, right, store1.Name, store2.Name);
                        return(false);
                    }
                }
                else if (!left.Untyped.Matches(right.Untyped))
                {
                    Log.DebugLine(this, "   {0} != {1}", left, right);
                    return(false);
                }
            }

            return(true);
        }
Пример #24
0
        private void DoVisit(TypedInstructionCollection instructions, BasicBlock block, int lastIndex, int prevIndex, int loopIndex)
        {
            DBC.Assert(m_visited.IndexOf(block) < 0, "{0} has already been visited", block);

            if (block.Length < 0 || block.First.Index <= lastIndex)
            {
//				Log.DebugLine(this, "visiting {0}", block);

                if (block.Length > 0)
                {
                    if (block.First.Index < prevIndex)
                    {
                        if (prevIndex > loopIndex)
                        {
                            loopIndex = prevIndex;
                        }
                    }

                    if (block.First.Index > loopIndex)
                    {
                        loopIndex = int.MinValue;
                    }
//					Log.DebugLine(this, "prevIndex: {0}, loopIndex: {1}", prevIndex, loopIndex);

                    // Visit each instruction in the block,
                    m_visited.Add(block);
                    for (int index = block.First.Index; index <= block.Last.Index; ++index)
                    {
                        TypedInstruction instruction = instructions[index];
                        if (instruction.Untyped.OpCode.Code == Code.Call || instruction.Untyped.OpCode.Code == Code.Callvirt)
                        {
                            MethodReference target = (MethodReference)instruction.Untyped.Operand;
                            m_callGraph.Add(instructions.Method, target);
                        }

                        m_looping = index <= loopIndex;
                        DoVisit(instruction);
                    }

                    // the finally block if we have one,
                    if (block.Finally != null && m_visited.IndexOf(block.Finally) < 0)
                    {
                        DoVisit(instructions, block.Finally, lastIndex, block.Last.Index, int.MinValue);
                    }

                    // the fault block if we have one,
                    else if (block.Fault != null && m_visited.IndexOf(block.Fault) < 0)
                    {
                        DoVisit(instructions, block.Fault, lastIndex, block.Last.Index, int.MinValue);
                    }
                }

                // and each block this block leads to.
                for (int index = 0; index < block.Next.Length; ++index)
                {
                    if (m_visited.IndexOf(block.Next[index]) < 0)
                    {
                        if (block.Length > 0)
                        {
                            DoVisit(instructions, block.Next[index], lastIndex, block.Last.Index, loopIndex);
                        }
                        else
                        {
                            DoVisit(instructions, block.Next[index], lastIndex, prevIndex, loopIndex);
                        }
                    }
                }
            }
        }
Пример #25
0
 internal BasicBlock(TypedInstruction first, TypedInstruction last)
 {
     First  = first;
     Last   = last;
     Length = Last.Index - First.Index + 1;
 }
Пример #26
0
        // 0F: br         29
        // 14: Ldarg.0    this
        // 15: ldfld      System.Object Smokey.Tests.UnusualMonitor1Test/Good1::m_lock
        // 1A: call       System.Boolean System.Threading.Monitor::Wait(System.Object)
        // 1F: box        System.Boolean
        // 24: call       System.Void *(System.Object)
        private bool DoMatch1a(int index)
        {
            bool match = false;

            do
            {
                if (index - 5 < 0 || index >= m_info.Instructions.Length)
                {
                    break;
                }

                TypedInstruction instruction = m_info.Instructions[index - 0];
                Code             code        = instruction.Untyped.OpCode.Code;
                if (code != Code.Call && code != Code.Callvirt)
                {
                    break;
                }
                if (!((Call)instruction).Target.ToString().StartsWith("System.Void ") || !((Call)instruction).Target.ToString().EndsWith("(System.Object)"))
                {
                    break;
                }

                instruction = m_info.Instructions[index - 1];
                code        = instruction.Untyped.OpCode.Code;
                if (code != Code.Box)
                {
                    break;
                }

                instruction = m_info.Instructions[index - 2];
                code        = instruction.Untyped.OpCode.Code;
                if (code != Code.Call && code != Code.Callvirt)
                {
                    break;
                }
                if (((Call)instruction).Target.ToString() != "System.Boolean System.Threading.Monitor::Wait(System.Object)")
                {
                    break;
                }

                instruction = m_info.Instructions[index - 3];
                code        = instruction.Untyped.OpCode.Code;
                if (code != Code.Ldfld)
                {
                    break;
                }

                instruction = m_info.Instructions[index - 4];
                code        = instruction.Untyped.OpCode.Code;
                if (code != Code.Ldarg_0)
                {
                    break;
                }

                instruction = m_info.Instructions[index - 5];
                code        = instruction.Untyped.OpCode.Code;
                if (code != Code.Br_S && code != Code.Br)
                {
                    break;
                }

                match = true;
            }while (false);

            return(match);
        }
Пример #27
0
 public DetermineTypesInstruction(TypedInstruction instruction)
     : this(instruction.inputTypes, instruction.outputTypes)
 {
 }
Пример #28
0
        private int DoGetStackCount(TypedInstruction instruction, StackBehaviour behavior)
        {
            int count = 0;

            switch (behavior)
            {
            case StackBehaviour.Pop0:
            case StackBehaviour.Push0:
                break;

            case StackBehaviour.Pop1:
            case StackBehaviour.Popi:
            case StackBehaviour.Popref:
            case StackBehaviour.Push1:
            case StackBehaviour.Pushi:
            case StackBehaviour.Pushi8:
            case StackBehaviour.Pushr4:
            case StackBehaviour.Pushr8:
            case StackBehaviour.Pushref:
                count = 1;
                break;

            case StackBehaviour.Pop1_pop1:
            case StackBehaviour.Popi_pop1:
            case StackBehaviour.Popi_popi:
            case StackBehaviour.Popi_popi8:
            case StackBehaviour.Popi_popr4:
            case StackBehaviour.Popi_popr8:
            case StackBehaviour.Popref_pop1:
            case StackBehaviour.Popref_popi:
            case StackBehaviour.Push1_push1:
                count = 2;
                break;

            case StackBehaviour.Popi_popi_popi:
            case StackBehaviour.Popref_popi_popi:
            case StackBehaviour.Popref_popi_popi8:
            case StackBehaviour.Popref_popi_popr4:
            case StackBehaviour.Popref_popi_popr8:
            case StackBehaviour.Popref_popi_popref:
                count = 3;
                break;

            case StackBehaviour.PopAll:                                                 // leave
                count = int.MaxValue;
                break;

            case StackBehaviour.Varpop:                                                 // call, newobj, ret
                Call call = instruction as Call;
                if (call != null)
                {
                    count = call.Target.Parameters.Count + (call.Target.HasThis ? 1 : 0);
                }
                else if (instruction.Untyped.OpCode.Code == Code.Ret)
                {
                    count = int.MaxValue;
                }
                else
                {
                    NewObj no = instruction as NewObj;
                    DBC.Assert(no != null, "Varpop opcode should be call, ret, or newobj");

                    count = no.Ctor.Parameters.Count;
                }
                break;

            case StackBehaviour.Varpush:                                        // call
                Call call2 = instruction as Call;
                DBC.Assert(call2 != null, "Varpush opcode should be call");
                if (call2.Target.ReturnType.ReturnType.FullName != "System.Void")
                {
                    count = 1;
                }
                break;

            default:
                DBC.Fail("Bad stack behavior: {0}", behavior);
                break;
            }

            return(count);
        }
Пример #29
0
        // ldarg.0
        // volatile.
        // stsfld bool Smokey.Tests.StaticSetterTest/Static::ms_vatomic
        private bool DoVolatileStore(StoreStaticField store)
        {
            TypedInstruction prior = m_info.Instructions[store.Index - 1];

            return(prior.Untyped.OpCode.Code == Code.Volatile);
        }
Пример #30
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"));
        }