Exemple #1
0
        /// <summary>
        /// Finds all the com objects in a given namespace and marks the methods of their subclasses as reachable.
        ///
        /// Perhaps too blunt.
        /// </summary>
        /// <param name="wholeProgram"></param>
        /// <param name="namespacePrefix"></param>
        /// <returns></returns>
        internal static ReachabilitySummary COMSummary(WholeProgram wholeProgram, String namespacePrefix)
        {
            // The ToString() here is probably not the best idea.
            IEnumerable <ITypeDefinition> comInterfaces = wholeProgram.AllDefinedTypes().Where(type => type.IsComObject &&
                                                                                               type.IsInterface &&
                                                                                               type.ToString().StartsWith("Microsoft.Cci"));

            ReachabilitySummary summary = new ReachabilitySummary();

            foreach (ITypeDefinition comInterface in comInterfaces)
            {
                summary.ReachableTypes.Add(comInterface);

                foreach (ITypeDefinition subtype in wholeProgram.ClassHierarchy().AllSubClassesOfClass(comInterface))
                {
                    summary.ConstructedTypes.Add(subtype);

                    foreach (IMethodDefinition method in subtype.Methods)
                    {
                        summary.NonvirtuallyCalledMethods.Add(method);
                    }
                }
            }

            return(summary);
        }
        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;
            }
        }
 public Translator getTranslator(Sink sink, IDictionary<IUnit, IContractProvider> contractProviders, IDictionary<IUnit, PdbReader> pdbReaders) {
   TraverserFactory factory;
   if (isWholeProgram)
     factory= new WholeProgram();
   else
     factory= new CLRSemantics();
   // Translator translator= factory.MakeMetadataTraverser(sink, contractProviders, pdbReaders);
   Translator translator= factory.getTranslator(sink, contractProviders, pdbReaders);
   return translator;
 }
Exemple #4
0
        static int Main(string[] args)
        {
            // populate options with command line args
            var options = Program.ParseOptions(args);

            if (options == null)
            {
                return(-1);
            }


            stopwatch.Start();

            using (var host = GetHostFromOptions(options)) {
                ISet <IAssembly> rootAssemblies = GetRootAssembliesFromOptions(options, host);

                WholeProgram wholeProgram = new WholeProgram(rootAssemblies, host);

                string reportPath = "ILGarbageCollectReport";
                if (!String.IsNullOrWhiteSpace(options.report))
                {
                    reportPath = options.report + @"\" + reportPath;
                }


                bool performMark  = (options.mode == RunMode.Mark || options.mode == RunMode.MarkAndSweep);
                bool performSweep = (options.mode == RunMode.Sweep || options.mode == RunMode.MarkAndSweep);

                if (performMark)
                {
                    IEnumerable <IMethodReference> entryPoints = GetEntryPointsFromOptions(options, wholeProgram);

                    IEnumerable <IMethodSummarizer> reflectionSummarizers = GetReflectionSummarizersFromOptions(options, wholeProgram);
                    RunRTA(wholeProgram, reflectionSummarizers, entryPoints, reportPath, options.profile);
                }

                if (performSweep)
                {
                    string transformPath = options.transform;

                    TransformProgram(wholeProgram, transformPath, reportPath, options.removal, options.profile);
                }
            }

            Console.WriteLine("Elapsed time: {0}", stopwatch.Elapsed);

            return(0);
        }
    public ReachabilitySummary SummarizeMethod(IMethodDefinition methodDefinition, WholeProgram wholeProgram) {
      // if there is an implementation available (e.g. we can get to opcodes)
      if (methodDefinition.IsExternal == false && methodDefinition.IsAbstract == false) {
        BytecodeVisitor visitor = new BytecodeVisitor();

        // foreach MSIL instruction in the method
        foreach (var op in methodDefinition.ResolvedMethod.Body.Operations) {
          visitor.Visit(op); // handle the opcode
        }

        return visitor.GetSummary();
      }
      else {
        return null;
      }
    }
Exemple #6
0
        public Translator getTranslator(Sink sink, IDictionary <IUnit, IContractProvider> contractProviders, IDictionary <IUnit, PdbReader> pdbReaders)
        {
            TraverserFactory factory;

            if (isWholeProgram)
            {
                factory = new WholeProgram();
            }
            else
            {
                factory = new CLRSemantics();
            }
            // Translator translator= factory.MakeMetadataTraverser(sink, contractProviders, pdbReaders);
            Translator translator = factory.getTranslator(sink, contractProviders, pdbReaders);

            return(translator);
        }
Exemple #7
0
        public RapidTypeAnalysis(WholeProgram wholeProgram, TargetProfile profile)
        {
            Contract.Ensures(!this.FinishedAnalysis);

            this.types   = new HashSet <ITypeDefinition>(new TypeDefinitionEqualityComparer());
            this.methods = new HashSet <IMethodDefinition>(new MethodDefinitionEqualityComparer());
            this.virtualCallsInDemand = new VirtualDispatchDemand();

            this.nonvirtualDispatches = new HashSet <IMethodDefinition>(new MethodDefinitionEqualityComparer());

            this.fields      = new HashSet <IFieldDefinition>(new FieldDefinitionEqualityComparer());
            this.constructed = new HashSet <ITypeDefinition>(new TypeDefinitionEqualityComparer());

            this.constructedGenericParameters = new HashSet <IGenericParameter>(new TypeDefinitionEqualityComparer());

            // Note: we use the interned key as the hashcode, so this set should be deterministic
            this.worklist = new HashSet <IMethodDefinition>(new MethodDefinitionEqualityComparer());

            this.wholeProgram = wholeProgram;

            this.reflectionSummarizers = new HashSet <IMethodSummarizer>();

            this.simpleBytecodeSummarizer           = new SimpleBytecodeMethodSummarizer();
            this.reachabilityFlowBytecodeSummarizer = new ReachabilityBasedLocalFlowMethodSummarizer();

            //systemObjectType = wholeProgram.Host().PlatformType.SystemObject.ResolvedType;

            // Weak heuristic -- should provide custom host?

            IAssembly coreAssembly = wholeProgram.HeuristicFindCoreAssemblyForProfile(profile);

            Contract.Assert(coreAssembly != null);

            systemObjectType = GarbageCollectHelper.CreateTypeReference(wholeProgram.Host(), coreAssembly, "System.Object").ResolvedType;
            Contract.Assert(!(systemObjectType is Dummy));

            systemObjectFinalizeMethod = TypeHelper.GetMethod(systemObjectType, wholeProgram.Host().NameTable.GetNameFor("Finalize"));
            Contract.Assert(!(systemObjectFinalizeMethod is Dummy));

            methodsRequiringReflectionSummary = new HashSet <IMethodDefinition>(new MethodDefinitionEqualityComparer());

            unresolvedReferences = new HashSet <IReference>(new ReferenceEqualityComparer());

            unspecializedTypesPassedAsTypeVariables = new HashSet <ITypeDefinition>(new TypeDefinitionEqualityComparer());
        }
    public RapidTypeAnalysis(WholeProgram wholeProgram, TargetProfile profile) {
      Contract.Ensures(!this.FinishedAnalysis);

      this.types = new HashSet<ITypeDefinition>(new TypeDefinitionEqualityComparer());
      this.methods = new HashSet<IMethodDefinition>(new MethodDefinitionEqualityComparer());
      this.virtualCallsInDemand = new VirtualDispatchDemand();

      this.nonvirtualDispatches = new HashSet<IMethodDefinition>(new MethodDefinitionEqualityComparer());

      this.fields = new HashSet<IFieldDefinition>(new FieldDefinitionEqualityComparer());
      this.constructed = new HashSet<ITypeDefinition>(new TypeDefinitionEqualityComparer());

      this.constructedGenericParameters = new HashSet<IGenericParameter>(new TypeDefinitionEqualityComparer());

      // Note: we use the interned key as the hashcode, so this set should be deterministic
      this.worklist = new HashSet<IMethodDefinition>(new MethodDefinitionEqualityComparer());

      this.wholeProgram = wholeProgram;

      this.reflectionSummarizers = new HashSet<IMethodSummarizer>();
     
      this.simpleBytecodeSummarizer = new SimpleBytecodeMethodSummarizer();
      this.reachabilityFlowBytecodeSummarizer = new ReachabilityBasedLocalFlowMethodSummarizer();

      //systemObjectType = wholeProgram.Host().PlatformType.SystemObject.ResolvedType;

      // Weak heuristic -- should provide custom host?

      IAssembly coreAssembly = wholeProgram.HeuristicFindCoreAssemblyForProfile(profile);
      Contract.Assert(coreAssembly != null);

      systemObjectType = GarbageCollectHelper.CreateTypeReference(wholeProgram.Host(), coreAssembly, "System.Object").ResolvedType;
      Contract.Assert(!(systemObjectType is Dummy));

      systemObjectFinalizeMethod = TypeHelper.GetMethod(systemObjectType, wholeProgram.Host().NameTable.GetNameFor("Finalize"));
      Contract.Assert(!(systemObjectFinalizeMethod is Dummy));

      methodsRequiringReflectionSummary = new HashSet<IMethodDefinition>(new MethodDefinitionEqualityComparer());

      unresolvedReferences = new HashSet<IReference>(new ReferenceEqualityComparer());

      unspecializedTypesPassedAsTypeVariables = new HashSet<ITypeDefinition>(new TypeDefinitionEqualityComparer());

    }
        private static IFieldDefinition LookupFieldWithIdentifier(string identifier, WholeProgram wholeProgram)
        {
            WholeProgramSearchQuery query = CreateQueryForIdentifier(identifier);

            ISet <IFieldDefinition> fields = wholeProgram.FindFieldsMatchingWholeProgramQuery(query);

            if (fields.Count() == 1)
            {
                return(fields.First());
            }
            else if (fields.Count() > 1)
            {
                throw new Exception("Couldn't find unique field with identifier " + identifier + " (found " + fields.Count() + ")");
            }
            else
            {
                throw new Exception("Couldn't find fields with identifier: " + identifier);
            }
        }
Exemple #10
0
        private static void TransformProgram(WholeProgram wholeProgram,
                                             string transformedBinariesPath,
                                             string reportsPath,
                                             MethodRemoval methodRemoval,
                                             TargetProfile profile)
        {
            System.IO.Directory.CreateDirectory(transformedBinariesPath);

            StubMethodBodyEmitter stubEmitter = GetStubMethodBodyEmitterForProfile(profile, wholeProgram);

            foreach (IAssembly assembly in wholeProgram.AllAssemblies())
            {
                if (AssemblyShouldBeRewritten(assembly))
                {
                    if (assembly.PublicKeyToken.Count() > 0)
                    {
                        Console.WriteLine("Warning: rewriting assembly with a public key token. {0}", assembly);
                    }

                    string outputBinary = transformedBinariesPath + @"\" + Path.GetFileName(assembly.Location);

                    var copy = new MetadataDeepCopier(wholeProgram.Host()).Copy(assembly);


                    DocumentationCommentDefinitionIdStringMap idMap = new DocumentationCommentDefinitionIdStringMap(new IAssembly[] { copy });

                    AssemblyReport assemblyReport = AssemblyReport.CreateAssemblyReportFromPath(copy, reportsPath, idMap);

                    stopwatch.Start();
                    RewriteBinary(copy, assemblyReport, wholeProgram.Host(), outputBinary, methodRemoval, stubEmitter);

                    stopwatch.Start();
                }
                else
                {
                    //Console.WriteLine("Skipping rewrite of of assembly {0}", assembly.Name.Value);
                }
            }
        }
Exemple #11
0
        private static RapidTypeAnalysis RunRTA(WholeProgram wholeProgram,
                                                IEnumerable <ILGarbageCollect.Summaries.IMethodSummarizer> reflectionSummarizers,
                                                IEnumerable <IMethodReference> entryPoints,
                                                string reportPath,
                                                TargetProfile profile)
        {
            var rta = new RapidTypeAnalysis(wholeProgram, profile);

            rta.ReflectionSummarizers = reflectionSummarizers;


            Console.WriteLine("Running Rapid Type Analysis with {0} entry points", entryPoints.Count());



            rta.Run(entryPoints);

            stopwatch.Stop();

            OutputRTAStatistics(rta, reportPath);


            return(rta);
        }
Exemple #12
0
        private static StubMethodBodyEmitter GetStubMethodBodyEmitterForProfile(TargetProfile profile, WholeProgram wholeProgram)
        {
            StubMethodBodyEmitter emitter;

            switch (profile)
            {
            case TargetProfile.Desktop:
                emitter = new DotNetDesktopStubMethodBodyEmitter(wholeProgram.Host());
                break;

            case TargetProfile.Phone:
                emitter = new WindowsPhoneStubMethodBodyEmitter(wholeProgram.Host());
                break;

            default:
                emitter = new DotNetDesktopStubMethodBodyEmitter(wholeProgram.Host());
                break;
            }

            return(emitter);
        }
        private static ISet <ITypeDefinition> LookupTypesWithSpecifier(TypeSpecifier specifier, WholeProgram wholeProgram)
        {
            HashSet <ITypeDefinition> result = new HashSet <ITypeDefinition>(new TypeDefinitionEqualityComparer());

            string typeIdentifier = specifier.TypeIdentifier;


            switch (specifier.Kind)
            {
            case TypeSpecifierKind.Exactly:
                result.Add(LookupExactTypeWithIdentifier(typeIdentifier, wholeProgram));
                break;

            case TypeSpecifierKind.Subtypes:
                // t-devinc: We really out to change this to include the type itself, not just all of its proper subtypes
                result.UnionWith(wholeProgram.ClassHierarchy().AllSubClassesOfClass(LookupExactTypeWithIdentifier(typeIdentifier, wholeProgram)));
                break;

            case TypeSpecifierKind.Matches:
                return(LookupTypesMatchingRegexpIdentifier(typeIdentifier, wholeProgram));
            }

            return(result);
        }
        private static ISet <ITypeDefinition> LookupTypesMatchingQuery(WholeProgramSearchQuery query, WholeProgram wholeProgram)
        {
            ISet <ITypeDefinition> types = wholeProgram.FindTypesMatchingWholeProgramQuery(query);

            if (types.Count() > 0)
            {
                return(types);
            }
            else
            {
                // Really should have function that turns query into a human readable string
                throw new Exception("Couldn't find any types matching query: " + query.AssemblySpecifier + "!" + query.DefinitionSpecifier);
            }
        }
        private static ITypeDefinition LookupExactTypeWithIdentifier(string identifier, WholeProgram wholeProgram)
        {
            WholeProgramSearchQuery query = CreateQueryForIdentifier(identifier);

            ISet <ITypeDefinition> types = LookupTypesMatchingQuery(query, wholeProgram);

            if (types.Count() == 1)
            {
                return(types.First());
            }
            else
            {
                throw new Exception("Couldn't find unique type with identifier: " + identifier + " (found " + types.Count() + ")");
            }
        }
        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.");
            }
        }
        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.");
            }
        }
Exemple #18
0
 abstract public ReachabilitySummary SummarizeMethod(IMethodDefinition methodDefinition, WholeProgram wholeProgram);
    private static IEnumerable<IMethodSummarizer> GetReflectionSummarizersFromOptions(ILGarbageCollectorOptions options, WholeProgram wholeProgram) {

      ISet<IMethodSummarizer> summarizers = DefaultReflectionSummarizers();

      string textSummariesPath = options.summaries;

      if (textSummariesPath != null) {
        TextFileMethodSummarizer textFileSummarizer = TextFileMethodSummarizer.CreateSummarizerFromPath(textSummariesPath, wholeProgram);
        summarizers.Add(textFileSummarizer);
      }

      return summarizers;
    }
    private static IEnumerable<IMethodReference> GetEntryPointsFromOptions(ILGarbageCollectorOptions options, WholeProgram wholeProgram) {

      ISet<IEntryPointDetector> entryPointDetectors = new HashSet<IEntryPointDetector>();

      bool ignoreMainEntryPoints = false;

      if (options.entrypoints != null) {
        entryPointDetectors.Add(new DocCommentFileEntryPointDetector(options.entrypoints));
        ignoreMainEntryPoints = true;
      }

      if (options.entryattributes != null) {
        entryPointDetectors.Add(new AttributeFileEntryPointDetector(options.entryattributes));
      }

      // If no entrypoints were directly specified are used, we'll just get the entry points
      // from the main assemblies.
      if (!ignoreMainEntryPoints) {
        entryPointDetectors.Add(new RootAssembliesEntryPointDetector());
      }

      ISet<IMethodReference> entryPoints = new HashSet<IMethodReference>();

      foreach (IEntryPointDetector entryPointDetector in entryPointDetectors) {
        entryPoints.UnionWith(entryPointDetector.GetEntryPoints(wholeProgram));
      }

      if (entryPoints.Count() == 0) {
        Console.WriteLine("Error: Could not find any entry points.");
        System.Environment.Exit(-1);
      }

      return entryPoints;
    }
    static int Main(string[] args) {

      // populate options with command line args
      var options = Program.ParseOptions(args);
      if (options == null) return -1;


      stopwatch.Start();

      using (var host = GetHostFromOptions(options)) {
        ISet<IAssembly> rootAssemblies = GetRootAssembliesFromOptions(options, host);

        WholeProgram wholeProgram = new WholeProgram(rootAssemblies, host);

        string reportPath = options.report + @"\" + "ILGarbageCollectReport";


        bool performMark = (options.mode == RunMode.Mark || options.mode == RunMode.MarkAndSweep);
        bool performSweep = (options.mode == RunMode.Sweep || options.mode == RunMode.MarkAndSweep);

        if (performMark) {
          IEnumerable<IMethodReference> entryPoints = GetEntryPointsFromOptions(options, wholeProgram);

          IEnumerable<IMethodSummarizer> reflectionSummarizers = GetReflectionSummarizersFromOptions(options, wholeProgram);
          RunRTA(wholeProgram, reflectionSummarizers, entryPoints, reportPath, options.profile);
        }

        if (performSweep) {
          string transformPath = options.transform;

          TransformProgram(wholeProgram, transformPath, reportPath, options.removal, options.profile);
        }

      }

      Console.WriteLine("Elapsed time: {0}", stopwatch.Elapsed);

      return 0;
    }
Exemple #22
0
        private static IEnumerable <IMethodReference> GetEntryPointsFromOptions(ILGarbageCollectorOptions options, WholeProgram wholeProgram)
        {
            ISet <IEntryPointDetector> entryPointDetectors = new HashSet <IEntryPointDetector>();

            bool ignoreMainEntryPoints = false;

            if (options.entrypoints != null)
            {
                entryPointDetectors.Add(new DocCommentFileEntryPointDetector(options.entrypoints));
                ignoreMainEntryPoints = true;
            }

            if (options.entryattributes != null)
            {
                entryPointDetectors.Add(new AttributeFileEntryPointDetector(options.entryattributes));
            }

            // If no entrypoints were directly specified are used, we'll just get the entry points
            // from the main assemblies.
            if (!ignoreMainEntryPoints)
            {
                entryPointDetectors.Add(new RootAssembliesEntryPointDetector());
            }

            ISet <IMethodReference> entryPoints = new HashSet <IMethodReference>();

            foreach (IEntryPointDetector entryPointDetector in entryPointDetectors)
            {
                entryPoints.UnionWith(entryPointDetector.GetEntryPoints(wholeProgram));
            }

            if (entryPoints.Count() == 0)
            {
                Console.WriteLine("Error: Could not find any entry points.");
                System.Environment.Exit(-1);
            }

            return(entryPoints);
        }
Exemple #23
0
        private static IEnumerable <IMethodSummarizer> GetReflectionSummarizersFromOptions(ILGarbageCollectorOptions options, WholeProgram wholeProgram)
        {
            ISet <IMethodSummarizer> summarizers = DefaultReflectionSummarizers();

            string textSummariesPath = options.summaries;

            if (textSummariesPath != null)
            {
                TextFileMethodSummarizer textFileSummarizer = TextFileMethodSummarizer.CreateSummarizerFromPath(textSummariesPath, wholeProgram);
                summarizers.Add(textFileSummarizer);
            }

            return(summarizers);
        }
Exemple #24
0
        public override ReachabilitySummary SummarizeMethod(IMethodDefinition methodDefinition, WholeProgram wholeProgram)
        {
            // Console.WriteLine("Running ReachabilityBasedLocalFlowMethodSummarizer on {0}", methodDefinition);

            ReachabilityStateAbstraction stateAbstraction = new ReachabilityStateAbstraction();
            ReachabilityStateInterpreter stateInterpreter = new ReachabilityStateInterpreter(stateAbstraction);


            var algorithm = new WorkListAlgorithm <ReachabilityStateInterpreter, ReachabilityStateAbstraction, bool>(stateInterpreter);

            algorithm.RunOnMethod(methodDefinition, wholeProgram.Host());

            SimpleBytecodeMethodSummarizer.BytecodeVisitor visitor = new SimpleBytecodeMethodSummarizer.BytecodeVisitor();


            foreach (BasicBlock <Instruction> block in algorithm.ControlFlowGraph.AllBlocks)
            {
                bool blockIsReachable = algorithm.GetBlockPostState(block);

                if (blockIsReachable)
                {
                    foreach (Instruction instruction in block.Instructions)
                    {
                        visitor.Visit(instruction.Operation);
                    }
                }
            }
            return(visitor.GetSummary());
        }
Exemple #25
0
        public override ReachabilitySummary SummarizeMethod(IMethodDefinition methodDefinition, WholeProgram wholeProgram)
        {
            //Console.WriteLine("Running AlwaysTopLocalFlowMethodSummarizer on {0}", methodDefinition);



            // hack to analyze on Foo<T> rather than Foo
            // since we need this for data flow

            // Unfortunately, this makes the CFG barf. Need to revisit later.

            /*
             * ITypeReference fullyInstantiatedSpecializedTypeReference;
             *
             * if (TypeHelper.TryGetFullyInstantiatedSpecializedTypeReference(methodDefinition.ContainingTypeDefinition, out fullyInstantiatedSpecializedTypeReference)) {
             * foreach (IMethodDefinition instantiatedMethod in fullyInstantiatedSpecializedTypeReference.ResolvedType.Methods) {
             *  if (GarbageCollectHelper.UnspecializeAndResolveMethodReference(instantiatedMethod).InternedKey == methodDefinition.InternedKey) {
             *    methodDefinition = instantiatedMethod;
             *    break;
             *  }
             * }
             * }
             */

            var valueAbstraction = new TypesValueAbstraction(wholeProgram.Host());


            var stateInterpreter = new VirtualCallRecordingStateInterpreter <TypesValueAbstraction, ITypeDefinition>(valueAbstraction);



            var algorithm = new WorkListAlgorithm <VirtualCallRecordingStateInterpreter <TypesValueAbstraction, ITypeDefinition>,
                                                   LocalsAndOperandsStateAbstraction <TypesValueAbstraction, ITypeDefinition>,
                                                   LocalsAndOperands <ITypeDefinition> >(stateInterpreter);

            try {
                algorithm.RunOnMethod(methodDefinition, wholeProgram.Host());
            }
            catch (Exception e) {
                if (e.GetType().FullName.Contains("ContractException"))
                {
                    // Very hokey, but it is what it is.
                    // Sometimes we fail because building the CFG fails, and occasionally
                    // we fail because of something in the analysis. In either event,
                    // we pick ourselves up and fall back on the regular summarization

                    // Need to record statistics on how often this happens.

                    Console.WriteLine("Got contract exception running local flow for " + methodDefinition);

                    return(new SimpleBytecodeMethodSummarizer().SummarizeMethod(methodDefinition, wholeProgram));
                }
                else
                {
                    throw;
                }
            }



            LocalFlowEnhancedBytecodeVisitor bytecodeVisitor = new LocalFlowEnhancedBytecodeVisitor();

            foreach (BasicBlock <Instruction> block in algorithm.ControlFlowGraph.AllBlocks)
            {
                foreach (Instruction instruction in block.Instructions)
                {
                    if (instruction.Operation.OperationCode == OperationCode.Callvirt)
                    {
                        ITypeDefinition valueAtReceiver = algorithm.StateInterpreter.ReceiverValueForVirtualCallInstruction(instruction.Operation);

                        Contract.Assert(valueAtReceiver != null);

                        //t-devinc: handle not resolving method gracefully.
                        IMethodDefinition compileTimeTargetMethod = (instruction.Operation.Value as IMethodReference).ResolvedMethod;

                        // The only way we allow the analysis to return a type that is a supertype of the type being dispatched upon is
                        // if we've gone to top (System.Object).
                        //
                        // This is really just a sanity check.
                        ITypeDefinition compileTimeType = compileTimeTargetMethod.ContainingTypeDefinition;

                        Contract.Assert(valueAtReceiver == wholeProgram.Host().PlatformType.SystemObject.ResolvedType ||
                                        TypeHelper.Type1DerivesFromOrIsTheSameAsType2(valueAtReceiver, compileTimeType) ||
                                        (compileTimeType.IsInterface && TypeHelper.Type1ImplementsType2(valueAtReceiver, compileTimeType)) ||
                                        (valueAtReceiver.IsInterface && compileTimeType == wholeProgram.Host().PlatformType.SystemObject.ResolvedType)
                                        );


                        bytecodeVisitor.NoteReceiverTypeForCallVirtual(valueAtReceiver, instruction.Operation);
                    }
                }
            }



            foreach (IOperation operation in methodDefinition.Body.Operations)
            {
                bytecodeVisitor.Visit(operation);
            }

            return(bytecodeVisitor.GetSummary());
        }
    private static RapidTypeAnalysis RunRTA(WholeProgram wholeProgram,
                                            IEnumerable<ILGarbageCollect.Summaries.IMethodSummarizer> reflectionSummarizers,
                                            IEnumerable<IMethodReference> entryPoints,
                                            string reportPath,
                                            TargetProfile profile) {





      var rta = new RapidTypeAnalysis(wholeProgram, profile);

      rta.ReflectionSummarizers = reflectionSummarizers;


      Console.WriteLine("Running Rapid Type Analysis with {0} entry points", entryPoints.Count());



      rta.Run(entryPoints);

      stopwatch.Stop();

      OutputRTAStatistics(rta, reportPath);


      return rta;
    }
        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.");
            }
        }
    private static StubMethodBodyEmitter GetStubMethodBodyEmitterForProfile(TargetProfile profile, WholeProgram wholeProgram) {
      StubMethodBodyEmitter emitter;

      switch (profile) {
        case TargetProfile.Desktop:
          emitter = new DotNetDesktopStubMethodBodyEmitter(wholeProgram.Host());
          break;
        case TargetProfile.Phone:
          emitter = new WindowsPhoneStubMethodBodyEmitter(wholeProgram.Host());
          break;
        default:
          emitter = new DotNetDesktopStubMethodBodyEmitter(wholeProgram.Host());
          break;
      }

      return emitter;
    }
 private static void InterpretCallVirtual(ReachabilitySummary summary, string methodIdentifier, WholeProgram wholeProgram)
 {
     if (summary != null)
     {
         IMethodDefinition method = LookupMethodWithIdentifier(methodIdentifier, wholeProgram);
         summary.VirtuallyCalledMethods.Add(method);
     }
     else
     {
         throw new Exception("Cannot call virtual  outside of a summarized method.");
     }
 }
        public ReachabilitySummary SummarizeMethod(IMethodDefinition methodDefinition, WholeProgram wholeProgram)
        {
            ReachabilitySummary summary = null;

            summariesByMethod.TryGetValue(methodDefinition, out summary);

            return(summary);
        }
 private static void InterpretWriteField(ReachabilitySummary summary, string methodIdentifier, WholeProgram wholeProgram)
 {
     if (summary != null)
     {
         IFieldDefinition field = LookupFieldWithIdentifier(methodIdentifier, wholeProgram);
         summary.ReachableFields.Add(field);
     }
     else
     {
         throw new Exception("Cannot use 'write' field outside of a summarized method.");
     }
 }
      public TestCompilerResults(IAssembly mainAssembly, IAssembly[] libraryAssemblies, PeReader.DefaultHost host) {
        this.MainAssembly = mainAssembly;

        this.Host = host;

        this.WholeProgram = new WholeProgram(new IAssembly[] { mainAssembly }, host);
      }
        private static ISet <ITypeDefinition> LookupTypesMatchingRegexpIdentifier(string identifier, WholeProgram wholeProgram)
        {
            WholeProgramSearchQuery query = CreateQueryForIdentifier(identifier);

            query.PerformRegexpMatch = true;

            return(LookupTypesMatchingQuery(query, wholeProgram));
        }
    static void ConstructWholeProgramForSources(string[] sources, WholeProgramResultDelegate resultDelegate) {
      // Each source is assumed to refer to all the sources before it

      CompileSourcesAndRun(sources, ".dll", compilerResult => {
        WholeProgram wholeProgram = new WholeProgram(new IAssembly[] { compilerResult.MainAssembly }, compilerResult.Host);

        resultDelegate(compilerResult, wholeProgram);
      });
    }
        private static ISet <ITypeDefinition> LookupTypesWithIdentifier(string identifier, WholeProgram wholeProgram)
        {
            WholeProgramSearchQuery query = CreateQueryForIdentifier(identifier);

            ISet <ITypeDefinition> types = wholeProgram.FindTypesMatchingWholeProgramQuery(query);

            if (types.Count() > 0)
            {
                return(types);
            }
            else
            {
                throw new Exception("Couldn't find type with identifier: " + identifier);
            }
        }
Exemple #36
0
        private ISet <ReachabilitySummary> RunReflectionSummarizers(IMethodDefinition method, WholeProgram wholeProgram)
        {
            ISet <ReachabilitySummary> summaries = new HashSet <ReachabilitySummary>();


            foreach (IMethodSummarizer reflectionSummarizer in reflectionSummarizers)
            {
                ReachabilitySummary summary = reflectionSummarizer.SummarizeMethod(method, wholeProgram);

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

            return(summaries);
        }
    private static void TransformProgram(WholeProgram wholeProgram,
        string transformedBinariesPath,
        string reportsPath,
        MethodRemoval methodRemoval,
        TargetProfile profile) {

      System.IO.Directory.CreateDirectory(transformedBinariesPath);

      StubMethodBodyEmitter stubEmitter = GetStubMethodBodyEmitterForProfile(profile, wholeProgram);

      foreach (IAssembly assembly in wholeProgram.AllAssemblies()) {
        if (AssemblyShouldBeRewritten(assembly)) {

          if (assembly.PublicKeyToken.Count() > 0) {
            Console.WriteLine("Warning: rewriting assembly with a public key token. {0}", assembly);
          }

          string outputBinary = transformedBinariesPath + @"\" + Path.GetFileName(assembly.Location);

          var copy = new MetadataDeepCopier(wholeProgram.Host()).Copy(assembly);


          DocumentationCommentDefinitionIdStringMap idMap = new DocumentationCommentDefinitionIdStringMap(new IAssembly[] { copy });

          AssemblyReport assemblyReport = AssemblyReport.CreateAssemblyReportFromPath(copy, reportsPath, idMap);

          stopwatch.Start();
          RewriteBinary(copy, assemblyReport, wholeProgram.Host(), outputBinary, methodRemoval, stubEmitter);

          stopwatch.Start();
        }
        else {
          //Console.WriteLine("Skipping rewrite of of assembly {0}", assembly.Name.Value);
        }
      }
    }
    /// <summary>
    /// Finds all the com objects in a given namespace and marks the methods of their subclasses as reachable.
    /// 
    /// Perhaps too blunt.
    /// </summary>
    /// <param name="wholeProgram"></param>
    /// <param name="namespacePrefix"></param>
    /// <returns></returns>
    internal static ReachabilitySummary COMSummary(WholeProgram wholeProgram, String namespacePrefix) {

      // The ToString() here is probably not the best idea.
      IEnumerable<ITypeDefinition> comInterfaces = wholeProgram.AllDefinedTypes().Where(type => type.IsComObject &&
                                                                                          type.IsInterface &&
                                                                                          type.ToString().StartsWith("Microsoft.Cci"));

      ReachabilitySummary summary = new ReachabilitySummary();

      foreach (ITypeDefinition comInterface in comInterfaces) {
        summary.ReachableTypes.Add(comInterface);

        foreach (ITypeDefinition subtype in wholeProgram.ClassHierarchy().AllSubClassesOfClass(comInterface)) {
          summary.ConstructedTypes.Add(subtype);

          foreach (IMethodDefinition method in subtype.Methods) {
            summary.NonvirtuallyCalledMethods.Add(method);
          }
        }
      }

      return summary;
    }
        public static TextFileMethodSummarizer CreateSummarizerFromPath(string path, WholeProgram wholeProgram)
        {
            TextFileMethodSummarizer summarizer = new TextFileMethodSummarizer();

            ReachabilitySummary summaryForCurrentMethod = null;

            foreach (string line in System.IO.File.ReadAllLines(path))
            {
                string trimmedLine = line.Trim();

                if (trimmedLine == "" || trimmedLine.StartsWith("#"))
                {
                    continue;
                }

                SummarizeCommand command = ParseCommand(trimmedLine);

                switch (command.Operation)
                {
                case SummarizeOperation.Summarize:
                    summaryForCurrentMethod = new ReachabilitySummary();
                    summarizer.summariesByMethod[LookupMethodWithIdentifier((string)command.Argument, wholeProgram)] = summaryForCurrentMethod;

                    break;

                case SummarizeOperation.Construct:
                    InterpretConstruct(summaryForCurrentMethod, (TypeSpecifier)command.Argument, wholeProgram);
                    break;

                case SummarizeOperation.ConstructAttributes:
                    InterpretConstructAttributes(summaryForCurrentMethod, (string)command.Argument, wholeProgram);
                    break;

                case SummarizeOperation.Call:
                    InterpretCall(summaryForCurrentMethod, (string)command.Argument, wholeProgram);
                    break;

                case SummarizeOperation.CallVirtual:
                    InterpretCallVirtual(summaryForCurrentMethod, (string)command.Argument, wholeProgram);
                    break;

                // We should really introduce a notion of a method specifier analogous to TypeSpecifier
                // that specifies a method, rather than have these separate operations for different ways to
                // specify methods

                case SummarizeOperation.CallAnyPublic:
                    InterpretCallAnyPublic(summaryForCurrentMethod, (TypeSpecifier)command.Argument, wholeProgram);
                    break;

                case SummarizeOperation.CallAny:
                    InterpretCallAny(summaryForCurrentMethod, (TypeSpecifier)command.Argument, wholeProgram);
                    break;

                case SummarizeOperation.ReadField:
                    InterpretReadField(summaryForCurrentMethod, (string)command.Argument, wholeProgram);
                    break;

                case SummarizeOperation.WriteField:
                    InterpretWriteField(summaryForCurrentMethod, (string)command.Argument, wholeProgram);
                    break;

                default:
                    throw new Exception("Unhandled summarize command: " + command.Operation + " " + command.Argument);
                }
            }

            return(summarizer);
        }
        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);
            }
        }
    static void ConstructClassHierarchyForSources(string[] sources, ClassHierarchyResultDelegate resultDelegate) {
      // Each source is assumed to refer to all the sources before it

      CompileSourcesAndRun(sources, ".dll", compilerResult => {
        WholeProgram wholeProgram = new WholeProgram(new IAssembly[] { compilerResult.MainAssembly }, compilerResult.Host);

        ClassHierarchy classHierarchy = new ClassHierarchy(wholeProgram.AllDefinedTypes(), compilerResult.Host);

        resultDelegate(compilerResult, classHierarchy);
      });
    }
        public ReachabilitySummary SummarizeMethod(IMethodDefinition methodDefinition, WholeProgram wholeProgram)
        {
            // if there is an implementation available (e.g. we can get to opcodes)
            if (methodDefinition.IsExternal == false && methodDefinition.IsAbstract == false)
            {
                BytecodeVisitor visitor = new BytecodeVisitor();

                // foreach MSIL instruction in the method
                foreach (var op in methodDefinition.ResolvedMethod.Body.Operations)
                {
                    visitor.Visit(op); // handle the opcode
                }

                return(visitor.GetSummary());
            }
            else
            {
                return(null);
            }
        }
    static void RunRTAOnSources(string[] sources, RTAResultDelegate runDelegate) {

      //The last source in the array must have the Main entrypoint

      CompileSourcesAndRun(sources, ".exe", compilerResult => {
        var mainAssembly = compilerResult.MainAssembly;

        WholeProgram wholeProgram = new WholeProgram(new IAssembly[] { compilerResult.MainAssembly }, compilerResult.Host);

        var rta = new RapidTypeAnalysis(wholeProgram, TargetProfile.Desktop);

        rta.Run(new IMethodDefinition[1] { mainAssembly.EntryPoint.ResolvedMethod });

        runDelegate(compilerResult, rta);
      });
    }
    private ISet<ReachabilitySummary> RunReflectionSummarizers(IMethodDefinition method, WholeProgram wholeProgram) {
      ISet<ReachabilitySummary> summaries = new HashSet<ReachabilitySummary>();
     

      foreach (IMethodSummarizer reflectionSummarizer in reflectionSummarizers) {
        ReachabilitySummary summary = reflectionSummarizer.SummarizeMethod(method, wholeProgram);

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

      return summaries;
    }