Пример #1
0
        /// <summary>Returns true if lhs is a subclass of rhs. Returns false if they are the same class.
        /// Interfaces are ignored.</summary>
        public static bool IsSubclassOf(this TypeReference lhs, string rhs, AssemblyCache cache)
        {
            DBC.Pre(lhs != null, "lhs is null");
            DBC.Pre(rhs != null, "rhs is null");
            DBC.Pre(cache != null, "cache is null");

            TypeDefinition type = cache.FindType(lhs);

            if (type != null && type.BaseType != null)
            {
                type = cache.FindType(type.BaseType);

                while (type != null)
                {
                    if (type.FullName == rhs)
                    {
                        return(true);
                    }

                    type = cache.FindType(type.BaseType);
                }
            }

            return(false);
        }
Пример #2
0
        internal void Register(object rule, string method, string name, string checkID)
        {
            DBC.Pre(rule != null, "rule is null");
            DBC.Pre(!string.IsNullOrEmpty(method), "method is null or empty");
            DBC.Pre(!string.IsNullOrEmpty(name), "name is null or empty");
            DBC.Pre(!string.IsNullOrEmpty(checkID), "checkID is null or empty");

            System.Reflection.MethodInfo mi = rule.GetType().GetMethod(method, BindingFlags.Public | BindingFlags.Instance);
            DBC.Pre(mi != null, "{0} isn't a public instance method of {1}", method, rule.GetType());
//	        Console.WriteLine("binding to {0}.{1}", rule.GetType(), method);
//          UntypedCallback callback = (UntypedCallback) Delegate.CreateDelegate(typeof(UntypedCallback), rule, mi);

            ParameterInfo[] pis = mi.GetParameters();
            DBC.Pre(pis.Length == 1, "{0}::{1} should only have one argument", rule.GetType().Name, method);
            Type type = pis[0].ParameterType;

            List <RuleCallback> callbacks;

            if (!m_callbackTable.TryGetValue(type, out callbacks))
            {
                callbacks = new List <RuleCallback>();
                m_callbackTable.Add(type, callbacks);
            }

            callbacks.Add(new RuleCallback(name, checkID, rule, mi));
        }
Пример #3
0
                public override Lattice Meet(Lattice lhs, Lattice rhs)
                {
                    DBC.Pre(lhs != null, "lhs is null");
                    DBC.Pre(rhs != null, "rhs is null");

                    // If one side is top then return the other side.
                    if (lhs.IsTop)
                    {
                        return(rhs);
                    }
                    else if (rhs.IsTop)
                    {
                        return(lhs);
                    }

                    // Otherwise we have to meet the two sides.	The result is
                    // indeterminate if one side is indeterminate or if the values
                    // differ.
                    if (!lhs.m_state.HasValue && !rhs.m_state.HasValue)                         // strictly speaking this case is not necessary but it saves us an allocation
                    {
                        return(lhs);
                    }

                    else if (!lhs.m_state.HasValue || !rhs.m_state.HasValue)
                    {
                        return(new Lattice(lhs.m_instructions, Indeterminate));
                    }

                    else if (lhs.m_state.Value == rhs.m_state.Value)
                    {
                        return(lhs);
                    }

                    return(new Lattice(lhs.m_instructions, Indeterminate));
                }
Пример #4
0
        public void VisitBegin(BeginMethod begin)
        {
            DBC.Pre(begin != null, "begin is null");

            Log.DebugLine(this, "-----------------------------------");
            Log.DebugLine(this, "{0:F}", begin.Info.Instructions);

            m_info = begin.Info;

            MethodDefinition method = begin.Info.Method;

            if (method.Name == "Finalize")
            {
                Log.DebugLine(this, "found finalizer: {0}", method);
                m_threadRoots.Add(method);
            }
            else if (method.ReturnType.ReturnType.ToString() == "System.Void")
            {
                if (method.Parameters.Count == 1 && method.Parameters[0].ParameterType.FullName == "System.IAsyncResult")
                {
                    Log.DebugLine(this, "found asynchronous thread function: {0}", method);
                    m_threadRoots.Add(method);
                }
            }
        }
Пример #5
0
        /// <summary>Returns the assembly the type is defined in.</summary>
        /// <summary>Returns null if the assembly cannot be found.</summary>
        public AssemblyDefinition FindAssembly(TypeReference type)
        {
            DBC.Pre(type != null, "type is null");

            AssemblyDefinition assembly = null;
            string             name     = type.FullName;

            if (!m_assemblies.TryGetValue(name, out assembly))
            {
                foreach (AssemblyDefinition candidate in m_depedent)
                {
                    foreach (ModuleDefinition module in candidate.Modules)
                    {
                        if (module.Types.Contains(name))
                        {
                            assembly = candidate;
                            m_assemblies.Add(name, assembly);
                            return(assembly);                                   // it's possible for internal types to have the exact same name in different assemblies so we'll bail as soon as we find one
                        }
                    }
                }
            }

            return(assembly);
        }
Пример #6
0
        /// <summary>Returns true if lhs is a subclass of rhs. Returns false if they are the same class.
        /// Interfaces are ignored.</summary>
        public static bool IsSubclassOf(this TypeReference lhs, TypeReference rhs, AssemblyCache cache)
        {
            DBC.Pre(lhs != null, "lhs is null");
            DBC.Pre(rhs != null, "rhs is null");
            DBC.Pre(cache != null, "cache is null");

            if (lhs.FullName != "System.Object" && rhs.FullName == "System.Object")             // everything is a subclass of object
            {
                return(true);
            }

            while (lhs != null)
            {
                TypeDefinition type = cache.FindType(lhs);

                lhs = type != null && !type.IsInterface ? type.BaseType : null;
                if (lhs != null)
                {
                    var key1 = new AssemblyCache.TypeKey(lhs);
                    var key2 = new AssemblyCache.TypeKey(rhs);
                    if (key1 == key2)
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
Пример #7
0
        /// <summary>Returns the interface or type the method was first declared in.</summary>
        public static TypeReference GetDeclaredIn(this MethodReference method, AssemblyCache cache)
        {
            DBC.Pre(method != null, "method is null");
            DBC.Pre(cache != null, "cache is null");

            TypeReference declared = method.DeclaringType;

            TypeReference candidate = DoGetDeclaringInterface(declared, new MethodMatcher(method), cache);

            if (candidate != null)
            {
                declared = candidate;
            }
            else
            {
                TypeDefinition baseType = cache.FindType(declared);
                if (baseType != null)
                {
                    Log.DebugLine(true, "   type: {0}", baseType);
                    baseType = cache.FindType(baseType.BaseType);
                    while (baseType != null && declared.FullName == method.DeclaringType.FullName)
                    {
                        Log.DebugLine(true, "   checking {0} for {1}", baseType, method.Name);
                        if (DoDeclares(baseType, new MethodMatcher(method)))
                        {
                            declared = baseType;
                        }

                        baseType = cache.FindType(baseType.BaseType);
                    }
                }
            }

            return(declared);
        }
Пример #8
0
            public Lattice(TypedInstructionCollection instructions, State state)
            {
                DBC.Pre(instructions != null, "instructions is null");

                m_instructions = instructions;
                m_state        = state;
            }
Пример #9
0
        /// <summary>Returns a TryCatch if the a block, catch block, or finally block
        /// starts at index. If a suitable TryCatch cannot be found null is returned.</summary>
        public TryCatch HandlerStartsAt(int index)
        {
            DBC.Pre(index >= 0, "index is negative");

            for (int i = 0; i < m_trys.Count; ++i)
            {
                if (m_trys[i].Try.Index == index)
                {
                    return(m_trys[i]);
                }

                for (int j = 0; j < m_trys[i].Catchers.Count; ++j)
                {
                    if (m_trys[i].Catchers[j].Index == index)
                    {
                        return(m_trys[i]);
                    }
                }

                if (m_trys[i].Finally.Index == index && m_trys[i].Finally.Length > 0)
                {
                    return(m_trys[i]);
                }

                else if (m_trys[i].Fault.Index == index && m_trys[i].Fault.Length > 0)
                {
                    return(m_trys[i]);
                }
            }

            return(null);
        }
Пример #10
0
                public override Lattice Meet(Lattice lhs, Lattice rhs)
                {
                    DBC.Pre(lhs != null, "lhs is null");
                    DBC.Pre(rhs != null, "rhs is null");

                    // If one side is top then return the other side.
                    if (lhs.IsTop)
                    {
                        return(rhs);
                    }
                    else if (rhs.IsTop)
                    {
                        return(lhs);
                    }

                    // Otherwise we have to meet the two sides.	The result is
                    // indeterminate if one side is indeterminate or if the
                    // values differ.
                    long?[]           args   = DoMeetVars(lhs.m_state.Arguments, rhs.m_state.Arguments);
                    long?[]           locals = DoMeetVars(lhs.m_state.Locals, rhs.m_state.Locals);
                    List <StackEntry> stack  = DoMeetStack(lhs.m_state.Stack, rhs.m_state.Stack);

                    State state = new State(args, locals, stack);

                    return(new Lattice(lhs.m_instructions, state));
                }
Пример #11
0
        public static bool Match(MethodReference lhs, MethodReference rhs)
        {
            DBC.Pre(lhs != null, "lhs is null");
            DBC.Pre(rhs != null, "rhs is null");

            if (lhs.Name != rhs.Name)
            {
                return(false);
            }

            if (lhs.Parameters.Count != rhs.Parameters.Count)
            {
                return(false);
            }

            for (int i = 0; i < lhs.Parameters.Count; ++i)
            {
                if (!DoMatchTypes(lhs, rhs, lhs.Parameters[i].ParameterType, rhs.Parameters[i].ParameterType))
                {
                    return(false);
                }
            }

            if (!DoMatchTypes(lhs, rhs, lhs.ReturnType.ReturnType, rhs.ReturnType.ReturnType))
            {
                return(false);
            }

            return(true);
        }
Пример #12
0
        // Typical usage is Add("-help", "-h", "-?", "blah blah"). The first string
        // is the primary option key used to identify the option. The middle strings
        // are aliaii for the primary key. The last string is the help text. Note
        // that the option can have a value if and only if the primary key ends with
        // '='. If the '=' is followed by text then that text is used as the default
        // value.
        public void Add(params string[] strs)
        {
            DBC.Pre(strs.Length >= 2, "{0} should have both a primary key and a help string", string.Join(", ", strs));
            DBC.Pre(!m_options.ContainsKey(strs[0]), "{0} was already added", strs[0]);

            string key   = strs[0];
            string value = null;
            int    i     = key.IndexOf("=");

            if (i >= 0)
            {
                key = strs[0].Substring(0, i);
                if (i + 1 < strs[0].Length)
                {
                    value = strs[0].Substring(i + 1);
                }
            }

            string help = strs[strs.Length - 1];

            string[] aliaii = new string[strs.Length - 2];              // TODO: should assert that there are no = in aliaii
            Array.Copy(strs, 1, aliaii, 0, strs.Length - 2);

            m_options[key] = new Option(key, value, help, i >= 0, aliaii);
        }
Пример #13
0
        public static bool HasDisableRule(this TypeDefinition derived, string checkID, AssemblyCache cache)
        {
            DBC.Pre(derived != null, "derived is null");
            DBC.Pre(checkID != null, "checkID is null");
            DBC.Pre(cache != null, "cache is null");

            TypeDefinition type = derived;

            while (type != null)
            {
                if (HasDisableRule(type.CustomAttributes, checkID))
                {
                    return(true);
                }

                foreach (TypeReference t in type.Interfaces)
                {
                    TypeDefinition td = cache.FindType(t);
                    if (td != null && HasDisableRule(td.CustomAttributes, checkID))
                    {
                        return(true);
                    }
                }

                type = cache.FindType(type.BaseType);
            }

            return(false);
        }
Пример #14
0
            public Tracker(TypedInstructionCollection instructions)
            {
                DBC.Pre(instructions != null, "instructions is null");

                m_instructions = instructions;
                m_initialState = DoGetInitialState(m_instructions);
            }
Пример #15
0
        public static bool IsCompilerGenerated(this TypeReference type)
        {
            DBC.Pre(type != null, "type is null");

            if (type.Name.Contains("CompilerGenerated"))
            {
                return(true);
            }

            else if (type.Name.Contains("AnonType"))
            {
                return(true);
            }

            else if (type.Name.Contains("AnonStore"))
            {
                return(true);
            }

            else if (type.Name.Contains(">c__"))
            {
                return(true);
            }

            else if (type.FullName.Contains("<PrivateImplementationDetails>"))
            {
                return(true);
            }

            return(false);
        }
Пример #16
0
        /// <summary>Returns true if the method has the specified result type, name, and argument types.
        /// Also see Reuses.</summary>
        public static bool Matches(this MethodReference method, string rtype, string mname, params string[] atypes)
        {
            DBC.Pre(method != null, "method is null");
            DBC.Pre(!string.IsNullOrEmpty(rtype), "rtype is null or empty");
            DBC.Pre(!string.IsNullOrEmpty(mname), "mname is null or empty");
            DBC.Pre(atypes != null, "atypes is null");

            bool match = false;

            if (method.ReturnType.ReturnType.FullName == rtype)
            {
                if (method.Name == mname)
                {
                    if (method.Parameters.Count == atypes.Length)
                    {
                        match = true;

                        for (int i = 0; i < atypes.Length && match; ++i)
                        {
                            match = atypes[i] == method.Parameters[i].ParameterType.FullName;
                        }
                    }
                }
            }

            return(match);
        }
Пример #17
0
        internal AssemblyCache(SymbolTable symbols, AssemblyDefinition assembly, Rule.KeepAliveCallback callback)
        {
            DBC.Pre(symbols != null, "symbols is null");
            DBC.Pre(assembly != null, "assembly is null");

            Profile.Start("AssemblyCache ctor");
            m_symbols  = symbols;
            m_assembly = assembly;

            // For some reason we have to force the Mdb assembly to load. If we don't it
            // isn't found.
            Unused.Value = typeof(Mono.Cecil.Mdb.MdbFactory);

            foreach (ModuleDefinition module in assembly.Modules)
            {
                try
                {
                    module.LoadSymbols();
                }
                catch
                {
                    Console.Error.WriteLine("Couldn't load symbols so there will be no file or line numbers.");
                }

                // Note that if the type is generic it will be listed once with a name like SomeType`1
                // where the number of the number of generic arguments.
                foreach (TypeDefinition type in module.Types)
                {
                    DoCheckForPublics(type);

                    TypeKey key = new TypeKey(type);
                    if (!m_types.ContainsKey(key))
                    {
                        m_types.Add(key, type);
                    }
                    else if (!type.FullName.Contains("CompilerGenerated"))
                    {
                        m_types[key] = type;                                                                                    // replace Database`1/<>c__CompilerGenerated5 with Database`1
                    }
                    Log.DebugLine(this, "adding {0}", type.FullName);
                    if (callback != null)
                    {
                        callback(string.Format("adding {0}", type.Name));
                    }

                    List <MethodInfo> ml = new List <MethodInfo>();
                    DoAddMethods(symbols, type, type.Constructors, ml);
                    DoAddMethods(symbols, type, type.Methods, ml);
                    m_typeMethods.Add(type, ml);
                }
            }

            DoLoadDependentAssemblies(callback);

            Profile.Stop("AssemblyCache ctor");
        }
Пример #18
0
            internal State(long?[] args, long?[] locals, List <StackEntry> stack)
            {
                DBC.Pre(args != null, "args is null");
                DBC.Pre(locals != null, "locals is null");
                DBC.Pre(stack != null, "stack is null");

                m_args   = args;
                m_locals = locals;
                m_stack  = stack;
            }
Пример #19
0
        protected Rule(AssemblyCache cache, IReportViolations reporter, string checkID)
        {
            DBC.Pre(cache != null, "cache is null");
            DBC.Pre(reporter != null, "reporter is null");
            DBC.Pre(!string.IsNullOrEmpty(checkID), "checkID is null or empty");

            Cache    = cache;
            Reporter = reporter;
            CheckID  = checkID;
            Runtime  = TargetRuntime.NET_1_0;
        }
Пример #20
0
        /// <summary>Returns the index of the instruction which pushed the method call's
        /// this argument onto the stack. May return -1 if a single such instruction
        /// could not be found.</summary>
        public int GetThisIndex(MethodInfo info)
        {
            DBC.Pre(info != null, "info is null");
            DBC.Pre(Target.HasThis, "the method is static");

            if (!m_thisIndex.HasValue)
            {
                m_thisIndex = info.Tracker.GetStackIndex(Index, Target.Parameters.Count);
            }

            return(m_thisIndex.Value);
        }
Пример #21
0
        /// <summary>Returns true if type is IntPtr, IntPtr[], List&lt;IntPtr&gt;, etc.</summary>
        public static bool IsNative(this TypeReference type)
        {
            DBC.Pre(type != null, "type is null");

            if (type.FullName.Contains("System.IntPtr") ||
                type.FullName.Contains("System.UIntPtr") ||
                type.FullName.Contains("System.Runtime.InteropServices.HandleRef"))
            {
                return(true);
            }

            return(false);
        }
Пример #22
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 out of range");                  // real code would probably use FastPre

                long?[]           args   = DoTransformArgs(index);
                long?[]           locals = DoTransformLocals(index);
                List <StackEntry> stack  = DoTransformStack(index);

                State state = new State(args, locals, stack);

                Log.DebugLine(this, "{0:X2}: {1}", m_instructions[index].Untyped.Offset, state);

                return(new Lattice(m_instructions, state));
            }
Пример #23
0
                public override bool DiffersFrom(Lattice lhs, Lattice rhs)
                {
                    DBC.Pre(lhs != null, "lhs is null");
                    DBC.Pre(rhs != null, "rhs is null");

                    if (lhs.IsTop || rhs.IsTop)                                         // if either side is indeterminate then we cant say the two sides are equal
                    {
                        return(true);
                    }
                    else
                    {
                        return(lhs.m_state != rhs.m_state);
                    }
                }
Пример #24
0
        private Dictionary <int, BasicBlock> DoGetWiredBlocks(TypedInstructionCollection instructions)
        {
            DBC.Pre(instructions.Length > 0, "Can't get a root if there are no instructions");

            m_branchTargets = new List <int>();
            Dictionary <int, BasicBlock> blocks = DoGetUnwiredBlocks(instructions);             // index -> block

            foreach (KeyValuePair <int, BasicBlock> entry in blocks)
            {
                DoWireBlock(instructions, blocks, entry.Value);
            }

            return(blocks);
        }
Пример #25
0
            public void Analyze(ControlFlowGraph graph)
            {
                DBC.Pre(graph != null, "graph is null");

                Profile.Start("Splicing");
                var visited = new List <BasicBlock>();

                foreach (BasicBlock root in graph.Roots)
                {
                    DoSpliceHandlers(m_instructions, root, visited);
                }

                visited.Clear();
                foreach (BasicBlock root in graph.Roots)
                {
                    DoSpliceNullCheck(m_instructions, root, visited);
                }
                var data = new DataFlow <Lattice>(m_instructions, graph.Roots);

                m_skipped = data.Skipped;
                Profile.Stop("Splicing");

                var functions = new Lattice.Functions();
                Dictionary <BasicBlock, Lattice> lattices = data.Analyze(functions, m_initialState);

                Profile.Start("Post Transform");
                m_states = new State[m_instructions.Length];
                foreach (var entry in lattices)
                {
                    BasicBlock block = entry.Key;
                    if (block.Length > 0)
                    {
                        Lattice lattice = entry.Value;

                        for (int index = block.First.Index; index <= block.Last.Index; ++index)                         // it'd be nice to assert that every index was set, but methods often have dead code so it's a little difficult
                        {
                            m_states[index] = lattice.State;
                            lattice         = lattice.Transform(index);
                        }
                    }
                }
                Profile.Stop("Post Transform");

                for (int index = 0; index < m_instructions.Length; ++index)
                {
                    Log.DebugLine(this, "{0:X2}: {1}", m_instructions[index].Untyped.Offset, m_states[index]);
                }
            }
Пример #26
0
        public static bool Has(this CustomAttributeCollection attrs, string name)
        {
            DBC.Pre(attrs != null, "attrs is null");
            DBC.Pre(name != null, "name is null");

            foreach (CustomAttribute attr in attrs)
            {
//				Log.InfoLine(true, "   {0}", attr.Constructor.DeclaringType.Name);
                if (attr.Constructor.DeclaringType.Name == name)                        // note that this is the type name, not the full name
                {
                    return(true);
                }
            }

            return(false);
        }
Пример #27
0
        public static bool IsCompilerGenerated(this MethodReference method)
        {
            DBC.Pre(method != null, "method is null");

            if (IsCompilerGenerated(method.DeclaringType))
            {
                return(true);
            }

            else if (method.Name[0] == '<')             // with 2.0 started getting weird names like <ArrayToStr>m__0
            {
                return(true);
            }

            return(false);
        }
Пример #28
0
        /// <summary>Returns true if field is created by type's constructor(s).</summary>
        public static bool IsOwnedBy(this FieldDefinition field, TypeDefinition type)
        {
            DBC.Pre(field != null, "field is null");
            DBC.Pre(type != null, "type is null");

            List <string> tested = new List <string>();

            for (int i = 0; i < type.Constructors.Count; ++i)
            {
                if (DoOwnsField(type, type.Constructors[i], field, tested))
                {
                    return(true);
                }
            }

            return(false);
        }
Пример #29
0
                public override Lattice Transform(Lattice lhs, BasicBlock block)
                {
                    DBC.Pre(lhs != null, "lhs is null");
                    DBC.Pre(block != null, "block is null");

                    Lattice result = lhs;

                    if (!lhs.IsTop)
                    {
                        for (int i = 0; i < block.Length; ++i)
                        {
                            result = result.Transform(block.First.Index + i);
                        }
                    }

                    return(result);
                }
Пример #30
0
        /// <summary>Returns true if type is an enum with the Flags attribute.</summary>
        public static bool IsFlagsEnum(this TypeDefinition type)
        {
            DBC.Pre(type != null, "type is null");

            if (type.IsEnum)
            {
                foreach (CustomAttribute attr in type.CustomAttributes)
                {
                    if (attr.Constructor.ToString().Contains("System.FlagsAttribute::.ctor"))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }