示例#1
0
        public override LocalsAndOperands <V> EntryPreState(IMethodDefinition method)
        {
            // entry pre-state is empty operand stack
            // with locals initialized
            //
            LocalsAndOperands <V> state = new LocalsAndOperands <V>();


            // If method has a this, parameter, it is the first argument

            if (!method.IsStatic && !method.HasExplicitThisParameter)
            {
                ITypeDefinition instantiatedThis = GarbageCollectHelper.InstantiatedTypeIfPossible(method.ContainingTypeDefinition);

                state.Arguments.Add(ValueAbstraction.GetAbstractValueForType(instantiatedThis));
            }

            foreach (IParameterDefinition parameter in method.Parameters)
            {
                state.Arguments.Add(ValueAbstraction.GetAbstractValueForType(parameter.Type.ResolvedType));
            }

            foreach (ILocalDefinition localVariable in method.Body.LocalVariables)
            {
                ITypeDefinition typeOfLocal = localVariable.Type.ResolvedType;

                state.Locals.Add(ValueAbstraction.GetAbstractValueForType(typeOfLocal));
            }

            return(state);
        }
示例#2
0
        public ISet <IMethodReference> GetEntryPoints(WholeProgram wholeProgram)
        {
            ISet <string> entryPointAttributeIDs = new HashSet <string>(System.IO.File.ReadAllLines(pathToFile));

            ISet <IMethodReference> foundEntryPoints   = new HashSet <IMethodReference>();
            ISet <string>           foundEntryPointIDs = new HashSet <string>();

            foreach (IMethodDefinition methodDefinition in wholeProgram.AllDefinedMethods())
            {
                foreach (ICustomAttribute attribute in methodDefinition.Attributes)
                {
                    string attributeDefinitionID = GarbageCollectHelper.GetIDStringForReference(attribute.Type);

                    if (entryPointAttributeIDs.Contains(attributeDefinitionID))
                    {
                        foundEntryPoints.Add(methodDefinition);
                        foundEntryPointIDs.Add(attributeDefinitionID);
                    }
                }
            }

            // A poor attempt at slightly more humane error-reporting
            foreach (string desiredEntryPointID in entryPointAttributeIDs)
            {
                if (!foundEntryPointIDs.Contains(desiredEntryPointID))
                {
                    Console.WriteLine("Couldn't find any entry points with attribute {0}", desiredEntryPointID);
                    Environment.Exit(-1);
                }
            }


            return(foundEntryPoints);
        }
示例#3
0
        public DotNetDesktopStubMethodBodyEmitter(IMetadataHost host)
            : base(host)
        {
            this.consoleWriteLine = new Microsoft.Cci.MethodReference(host,
                                                                      GarbageCollectHelper.CreateTypeReference(host, coreAssemblyReference, "System.Console"),
                                                                      CallingConvention.Default,
                                                                      host.PlatformType.SystemVoid,
                                                                      host.NameTable.GetNameFor("WriteLine"),
                                                                      0,
                                                                      host.PlatformType.SystemString);

            this.environmentGetStackTrace = new Microsoft.Cci.MethodReference(host,
                                                                              GarbageCollectHelper.CreateTypeReference(host, coreAssemblyReference, "System.Environment"),
                                                                              CallingConvention.Default,
                                                                              host.PlatformType.SystemString,
                                                                              host.NameTable.GetNameFor("get_StackTrace"),
                                                                              0);

            this.environmentExit = new Microsoft.Cci.MethodReference(host,
                                                                     GarbageCollectHelper.CreateTypeReference(host, coreAssemblyReference, "System.Environment"),
                                                                     CallingConvention.Default,
                                                                     host.PlatformType.SystemVoid,
                                                                     host.NameTable.GetNameFor("Exit"),
                                                                     0,
                                                                     host.PlatformType.SystemInt32);
        }
        private static void InterpretCallAny(ReachabilitySummary summary, TypeSpecifier typeSpecifier, WholeProgram wholeProgram)
        {
            if (summary != null)
            {
                foreach (ITypeDefinition type in LookupTypesWithSpecifier(typeSpecifier, wholeProgram))
                {
                    // Note, for now this only looks at methods directly defined on that type
                    // not on any methods defined on super types (and inherited).
                    // This is probably not what we really want to expose to the user.
                    foreach (IMethodDefinition method in type.Methods)
                    {
                        if (!method.IsAbstract)
                        {
                            summary.NonvirtuallyCalledMethods.Add(method);

                            // If there is a constructor, we treat the type as constructed
                            if (method.IsConstructor && GarbageCollectHelper.TypeIsConstructable(type))
                            {
                                summary.ConstructedTypes.Add(type);
                            }
                        }
                    }
                }
            }
            else
            {
                throw new Exception("Cannot call any outside of a summarized method.");
            }
        }
示例#5
0
        public WindowsPhoneStubMethodBodyEmitter(IMetadataHost host)
            : base(host)
        {
            this.consoleWriteLine = new Microsoft.Cci.MethodReference(host,
                                                                      GarbageCollectHelper.CreateTypeReference(host, coreAssemblyReference, "System.Console"),
                                                                      CallingConvention.Default,
                                                                      host.PlatformType.SystemVoid,
                                                                      host.NameTable.GetNameFor("WriteLine"),
                                                                      0,
                                                                      host.PlatformType.SystemString);

            this.stackTraceConstructor = new Microsoft.Cci.MethodReference(host,
                                                                           GarbageCollectHelper.CreateTypeReference(host, coreAssemblyReference, "System.Diagnostics.StackTrace"),
                                                                           CallingConvention.HasThis,
                                                                           host.PlatformType.SystemVoid,
                                                                           host.NameTable.GetNameFor(".ctor"),
                                                                           0);

            this.toString = new Microsoft.Cci.MethodReference(host,
                                                              host.PlatformType.SystemObject,
                                                              CallingConvention.HasThis,
                                                              host.PlatformType.SystemString,
                                                              host.NameTable.GetNameFor("ToString"),
                                                              0);
        }
示例#6
0
        public WholeProgram(IEnumerable <IAssembly> rootAssemblies, MetadataReaderHost host)
        {
            this.rootAssemblies = new HashSet <IAssembly>(rootAssemblies);

            this.allAssemblies = GarbageCollectHelper.CloseAndResolveOverReferencedAssemblies(rootAssemblies);

            this.host = host;
        }
示例#7
0
        private void WriteDefinitionIdentifiersToFile(IEnumerable <IDefinition> definitions, string path)
        {
            using (StreamWriter outfile = new StreamWriter(path)) {
                foreach (var definition in definitions)
                {
                    string definitionID = GarbageCollectHelper.GetIDStringForReference(definition);

                    outfile.WriteLine(definitionID);
                }
            }
        }
示例#8
0
        public IMethodDefinition FindMethodWithIdentifierInAssembly(string docCommentMethodIdentifier, IAssembly assembly)
        {
            // We could be more efficient here, but for now we go with simplicity
            foreach (IMethodDefinition method in GetAllMethodsInAssembly(assembly))
            {
                if (GarbageCollectHelper.GetIDStringForReference(method) == docCommentMethodIdentifier)
                {
                    return(method);
                }
            }

            return(null);
        }
示例#9
0
        private ITypeDefinition FixupTypeForFlow(ITypeDefinition type)
        {
            // If the type is generic but we're not instantiated, we try to instantiate it.
            // This is required because the CFG is over the completely unspecialized uninstantiated
            // bytecode while but some instruction *types* (e.g. calls) require instantiate types.

            // This has got to be slow.

            // Another alternative would have been to constrcut the CFG over the instantiated type
            // but this appears to be buggy at the moment.


            return(GarbageCollectHelper.InstantiatedTypeIfPossible(type));
        }
示例#10
0
        internal override void Visit(IOperation op)
        {
            if (op.OperationCode == OperationCode.Callvirt)
            {
                IMethodDefinition compileTimeTargetMethod = ResolveMethodReference(op.Value as IMethodReference);

                if (compileTimeTargetMethod != null && compileTimeTargetMethod.IsVirtual)
                {
                    // we have a callvirt to a virtual method
                    // so lets use the local flow information

                    //summary.VirtuallyCalledMethods.Add(target);

                    ITypeDefinition tightenedReceiverType;

                    if (receiverTypesByCallvirtOperation.TryGetValue(op, out tightenedReceiverType))
                    {
                        if (!tightenedReceiverType.IsInterface && TypeHelper.Type1DerivesFromOrIsTheSameAsType2(tightenedReceiverType, compileTimeTargetMethod.ContainingType))
                        {
                            //Console.WriteLine("Value at receiver is {0}", valueAtReceiver);

                            //Console.WriteLine("Will look up {0} in {1}", compileTimeTargetMethod, tightenedReceiverType);

                            IMethodDefinition tightenedMethod = GarbageCollectHelper.ImplementsInstantiated(tightenedReceiverType, compileTimeTargetMethod);



                            if (tightenedMethod != null)
                            {
                                if (tightenedMethod != compileTimeTargetMethod)
                                {
                                    //Console.WriteLine("Tightened method is {0} (from {1})", tightenedMethod, compileTimeTargetMethod);
                                }


                                // Yay, all the flow analysis paid off!
                                GetSummary().VirtuallyCalledMethods.Add(tightenedMethod);

                                //GetSummary().VirtuallyCalledMethods.Add(compileTimeTargetMethod);
                                return;
                            }
                        }
                    }
                }
            }

            // If we've gotten here, we fall back to normal handling
            base.Visit(op);
        }
示例#11
0
        protected void AppendEmitExceptionThrow(ILGenerator generator)
        {
            var systemExceptionTypeReference = GarbageCollectHelper.CreateTypeReference(host, coreAssemblyReference, "System.Exception");

            IMethodReference exceptionConstructor = new Microsoft.Cci.MethodReference(
                host,
                systemExceptionTypeReference,
                CallingConvention.HasThis,
                host.PlatformType.SystemVoid,
                host.NameTable.Ctor,
                0);

            generator.Emit(OperationCode.Newobj, exceptionConstructor);
            generator.Emit(OperationCode.Throw);
        }
示例#12
0
        public ISet <IDefinition> FindDefinitionsMatchingRegularExpressionInAssembly(Regex regex, IAssembly assembly)
        {
            // Maybe figure out how to factor out commons parts of this with FindDefinitionWithIdentifierInAssembly?

            ISet <IDefinition> results = new HashSet <IDefinition>(new DefinitionEqualityComparer());

            string regexPattern = regex.ToString();

            // We could be more efficient here, but for now we go with simplicity

            if (regexPattern.StartsWith("M:"))
            {
                foreach (IMethodDefinition method in GetAllMethodsInAssembly(assembly))
                {
                    if (regex.IsMatch(GarbageCollectHelper.GetIDStringForReference(method)))
                    {
                        results.Add(method);
                    }
                }
            }
            else if (regexPattern.StartsWith("T:"))
            {
                foreach (ITypeDefinition type in assembly.GetAllTypes())
                {
                    if (regex.IsMatch(GarbageCollectHelper.GetIDStringForReference(type)))
                    {
                        results.Add(type);
                    }
                }
            }
            else if (regexPattern.StartsWith("F:"))
            {
                foreach (IFieldDefinition field in GetAllFieldsInAssembly(assembly))
                {
                    if (regex.IsMatch(GarbageCollectHelper.GetIDStringForReference(field)))
                    {
                        results.Add(field);
                    }
                }
            }
            else
            {
                throw new Exception("Un recognized doc comment definition identifier prefix in: " + regexPattern + " (expected T:, M:, or F:)");
            }


            return(results);
        }
        private static void InterpretConstructAttributes(ReachabilitySummary summary, string fieldIdentifier, WholeProgram wholeProgram)
        {
            if (summary != null)
            {
                // For now we assume the argument is a field -- we really should support types and methods too
                IFieldDefinition fieldWithAttributes = LookupFieldWithIdentifier(fieldIdentifier, wholeProgram);


                foreach (ICustomAttribute customAttribute in fieldWithAttributes.Attributes)
                {
                    IMethodDefinition constructorDefinition = GarbageCollectHelper.UnspecializeAndResolveMethodReference(customAttribute.Constructor);

                    ITypeDefinition constructorType = constructorDefinition.ContainingTypeDefinition;

                    // Mark attribute constructor reachable
                    summary.NonvirtuallyCalledMethods.Add(constructorDefinition);


                    // Mark named argument property setters reachable
                    foreach (IMetadataNamedArgument namedArgument in customAttribute.NamedArguments)
                    {
                        IName setterName = wholeProgram.Host().NameTable.GetNameFor("set_" + namedArgument.ArgumentName.Value);

                        IMethodDefinition setterMethod = TypeHelper.GetMethod(constructorType, setterName, namedArgument.ArgumentValue.Type);

                        if (setterMethod != Dummy.Method)
                        {
                            // We treat this as a non-virtual call because we know the exact runtime-type of the attribute
                            summary.NonvirtuallyCalledMethods.Add(setterMethod);
                        }
                        else
                        {
                            // Note this won't find a property defined in a super class of the attribute (unsound).
                            // We'll want to fix this if try to generalize this code to handle arbitrary attributes

                            throw new Exception("Couldn't find setter " + setterName + " for type " + namedArgument.ArgumentValue.Type + " in " + constructorType);
                        }
                    }
                }
            }
            else
            {
                throw new Exception("Cannot construct subtypes outside of a summarized method.");
            }
        }
示例#14
0
        public IDefinition FindDefinitionWithIdentifierInAssembly(string docCommentIdentifier, IAssembly assembly)
        {
            // We could be more efficient here, but for now we go with simplicity

            if (docCommentIdentifier.StartsWith("M:"))
            {
                foreach (IMethodDefinition method in GetAllMethodsInAssembly(assembly))
                {
                    if (GarbageCollectHelper.GetIDStringForReference(method) == docCommentIdentifier)
                    {
                        return(method);
                    }
                }
            }
            else if (docCommentIdentifier.StartsWith("T:"))
            {
                foreach (ITypeDefinition type in assembly.GetAllTypes())
                {
                    if (GarbageCollectHelper.GetIDStringForReference(type) == docCommentIdentifier)
                    {
                        return(type);
                    }
                }
            }
            else if (docCommentIdentifier.StartsWith("F:"))
            {
                foreach (IFieldDefinition field in GetAllFieldsInAssembly(assembly))
                {
                    if (GarbageCollectHelper.GetIDStringForReference(field) == docCommentIdentifier)
                    {
                        return(field);
                    }
                }
            }
            else
            {
                throw new Exception("Un recognized doc comment definition identifier prefix in: " + docCommentIdentifier + " (expected T:, M:, or F:)");
            }


            return(null);
        }
示例#15
0
        internal DocumentationCommentDefinitionIdStringMap(IEnumerable <IAssembly> assemblies)
        {
            foreach (IAssembly assembly in assemblies)
            {
                foreach (ITypeDefinition typeDefinition in assembly.GetAllTypes())
                {
                    AddIdStringForDefinition(GarbageCollectHelper.GetIDStringForReference(typeDefinition), typeDefinition);

                    foreach (IMethodDefinition methodDefinition in typeDefinition.Methods)
                    {
                        AddIdStringForDefinition(GarbageCollectHelper.GetIDStringForReference(methodDefinition), methodDefinition);
                    }

                    foreach (IFieldDefinition fieldDefinition in typeDefinition.Fields)
                    {
                        AddIdStringForDefinition(GarbageCollectHelper.GetIDStringForReference(fieldDefinition), fieldDefinition);
                    }
                }
            }
        }
示例#16
0
        private static bool MethodIsCustomAttributeConstructor(IMethodDefinition methodDefinition)
        {
            if (methodDefinition.IsConstructor)
            {
                foreach (ITypeDefinition superClass in GarbageCollectHelper.AllSuperClasses(methodDefinition.ContainingTypeDefinition))
                {
                    if (superClass is INamedTypeDefinition)
                    {
                        // t-devinc: Could be more principled here, for sure
                        string typeName = superClass.ToString();
                        if (typeName.Equals("System.Attribute"))
                        {
                            return(true);
                        }
                    }
                }
            }

            return(false);
        }
示例#17
0
        internal ClassHierarchy(IEnumerable <ITypeDefinition> allTypes, IMetadataReaderHost host)
        {
            this.host = host;

            foreach (ITypeDefinition typeDefinition in allTypes)
            {
                Contract.Assert(GarbageCollectHelper.TypeDefinitionIsUnspecialized(typeDefinition));

                foreach (ITypeDefinition superType in GarbageCollectHelper.BaseClasses(typeDefinition))
                {
                    NoteClassIsSubClassOfClass(typeDefinition, GarbageCollectHelper.UnspecializeAndResolveTypeReference(superType));
                }

                // We treat every interface type as a subtype of System.Object
                if (typeDefinition.IsInterface)
                {
                    //NoteClassIsSubClassOfClass(instantiatedSubType, host.PlatformType.SystemObject.ResolvedType);
                    NoteClassIsSubClassOfClass(typeDefinition, host.PlatformType.SystemObject.ResolvedType);
                }
            }
        }
        private static void InterpretConstruct(ReachabilitySummary summary, TypeSpecifier typeSpecifier, WholeProgram wholeProgram)
        {
            if (summary != null)
            {
                foreach (ITypeDefinition typeToConstruct in LookupTypesWithSpecifier(typeSpecifier, wholeProgram))
                {
                    if (GarbageCollectHelper.TypeIsConstructable(typeToConstruct))
                    {
                        summary.ConstructedTypes.Add(typeToConstruct);

                        // now we mark ALL the non-private constructors as reachable. This is perhaps too imprecise
                        // an alternative would be to allow the user to specify the constructor signature.
                        MarkNonPrivateConstructorsReachableForType(summary, typeToConstruct);
                    }
                }
            }
            else
            {
                throw new Exception("Cannot construct type outside of a summarized method.");
            }
        }
            internal virtual void Visit(IOperation op)
            {
                IMethodDefinition target;

                switch (op.OperationCode)
                {
                case OperationCode.Newobj:
                    target = ResolveMethodReference(op.Value as IMethodReference);

                    if (target != null)
                    {
                        Contract.Assert(!(target is Dummy));

                        if (target.ContainingType is INamedTypeReference)
                        {
                            //Console.WriteLine("Got newobj to {0}", ((INamedTypeReference)target.ContainingType).Name);
                        }

                        ITypeDefinition constructedType = target.ContainingType.ResolvedType;
                        Contract.Assert(GarbageCollectHelper.TypeIsConstructable(constructedType));

                        summary.ReachableTypes.Add(constructedType);
                        summary.ConstructedTypes.Add(constructedType);
                        summary.NonvirtuallyCalledMethods.Add(target);
                    }
                    break;

                case OperationCode.Box:
                    // Boxing a struct means a callvirt could possibly
                    // dispatch to one of its methods.

                    ITypeDefinition boxedType = ResolveTypeReference(op.Value as ITypeReference);

                    if (boxedType != null)
                    {
                        // Guard for structs here because box to a reference type is a no-op but allowed and
                        // the Code Contracts instrumentation does this.
                        if (boxedType.IsStruct)
                        {
                            Contract.Assert(GarbageCollectHelper.TypeIsConstructable(boxedType));
                            summary.ConstructedTypes.Add(boxedType);
                        }
                    }
                    break;


                case OperationCode.Ldtoken:
                    if (op.Value is IFieldReference)
                    {
                        IFieldDefinition field = ResolveFieldReference(op.Value as IFieldReference);

                        if (field != null)
                        {
                            summary.ReachableFields.Add(field);
                        }
                    }

                    // t-devinc: Need to handle: method and type tokens, as well as generics.
                    // Fully supporting generics here may be very tricky -- this is a place
                    // where operating over specialized bytecode could perhaps help.
                    break;

                /* Notes on call/callvirt:
                 *
                 * We can get a call on a virtual method when that method is called via 'base'
                 * We can also get a callvirt on a non-virtual method whenever the compiler
                 * feels like it? This seems a little wonky.
                 */
                case OperationCode.Ldftn:
                case OperationCode.Call:
                    target = ResolveMethodReference(op.Value as IMethodReference);

                    if (target != null)
                    {
                        if (target.ContainingType is INamedTypeReference)
                        {
                            //Console.WriteLine("Got call to {0}", target);
                        }

                        summary.NonvirtuallyCalledMethods.Add(target);

                        if (target.Name.Value == "CreateInstance")
                        {
                            // t-devinc: gross, clean this up

                            INamespaceTypeDefinition containingTypeDefinition = target.ContainingTypeDefinition as INamespaceTypeDefinition;
                            if (containingTypeDefinition != null && containingTypeDefinition.Name.Value == "Activator")
                            {
                                if (containingTypeDefinition.ContainingNamespace.Name.Value == "System")
                                {
                                    IGenericMethodInstance targetAsGenericMethodInstance = target as IGenericMethodInstance;

                                    if (targetAsGenericMethodInstance != null)
                                    {
                                        // We have a call to 'new T()';
                                        ITypeDefinition definitionForT = targetAsGenericMethodInstance.GenericArguments.First().ResolvedType;

                                        summary.ConstructedTypeParameters.Add((IGenericParameter)definitionForT);
                                    }
                                }
                            }
                        }
                    }
                    break;

                case OperationCode.Ldvirtftn:
                case OperationCode.Callvirt:

                    target = ResolveMethodReference(op.Value as IMethodReference);

                    if (target != null)
                    {
                        if (target.ContainingType is INamedTypeReference)
                        {
                            //Console.WriteLine("Got callvirt to {0}", target);
                        }

                        if (target.IsVirtual)
                        {
                            summary.VirtuallyCalledMethods.Add(target);
                        }
                        else
                        {
                            // In its infinite wisdom, sometimes the compiler gives us a callvirt on a non-virtual method

                            summary.NonvirtuallyCalledMethods.Add(target);
                        }
                    }
                    break;

                case OperationCode.Ldfld:
                case OperationCode.Ldflda:
                case OperationCode.Ldsfld:
                case OperationCode.Ldsflda:

                /* For now we treat loads and stores as the same -- we'll want to be smarter about this in the future */
                case OperationCode.Stfld:
                case OperationCode.Stsfld:
                    IFieldDefinition fieldDefinition = ResolveFieldReference(op.Value as IFieldReference);

                    if (fieldDefinition != null)
                    {
                        summary.ReachableTypes.Add(fieldDefinition.ContainingTypeDefinition);
                        summary.ReachableFields.Add(fieldDefinition);
                    }
                    break;

                default:
                    break;
                }
            }
        public ReachabilitySummary SummarizeMethod(IMethodDefinition method, WholeProgram wholeProgram)
        {
            if (method.IsExternal == false && method.IsAbstract == false)
            {
                ReachabilitySummary summary = new ReachabilitySummary();
                IMethodDefinition   target;


                // foreach MSIL instruction in the method
                foreach (var op in method.Body.Operations)
                {
                    switch (op.OperationCode)
                    {
                    // non virtual method calls: just add static type
                    case OperationCode.Newobj:
                    case OperationCode.Call:
                    case OperationCode.Calli:
                        target = (op.Value as IMethodReference).ResolvedMethod;
                        summary.NonvirtuallyCalledMethods.Add(target);
                        break;

                    case OperationCode.Ldvirtftn:
                    case OperationCode.Callvirt:
                        target = (op.Value as IMethodReference).ResolvedMethod;

                        if (target.IsVirtual == false)
                        {
                            summary.NonvirtuallyCalledMethods.Add(target);
                        }
                        else
                        {
                            ITypeDefinition   typeDefiningTarget  = target.ContainingTypeDefinition;
                            IMethodDefinition targetUnspecialized = GarbageCollectHelper.UnspecializeAndResolveMethodReference(op.Value as IMethodReference);

                            // find all possible implementations of virtual call
                            foreach (ITypeDefinition subType in new ITypeDefinition[] { typeDefiningTarget }.Concat(wholeProgram.ClassHierarchy().AllSubClassesOfClass(typeDefiningTarget)))
                            {
                                if (GarbageCollectHelper.TypeIsConstructable(subType))
                                {
                                    // walk class hierarchy from subType up to (including) typeDefiningTarget, looking for targetUnspecialized.
                                    ICollection <IMethodDefinition> implementationsOfMethodDefinitionForSubType = GarbageCollectHelper.Implements(subType, typeDefiningTarget, targetUnspecialized);

                                    // we have to have found at least 1 implementation
                                    Contract.Assert(implementationsOfMethodDefinitionForSubType.Count() > 0);

                                    // add all of them as virtually called methods
                                    foreach (IMethodDefinition implementationOfTarget in implementationsOfMethodDefinitionForSubType)
                                    {
                                        summary.VirtuallyCalledMethods.Add(implementationOfTarget);
                                    }
                                }
                            }
                        }
                        break;

                    default:
                        break;
                    }
                }

                return(summary);
            }
            else
            {
                return(null);
            }
        }