Exemplo n.º 1
0
        /// <summary>
        /// Traverse the given assembly (located in options.Assembly) for contracts and return the contracts.
        /// </summary>
        /// <remarks>
        /// We use dictionary mapping special string ids that are unique to each member in an XML file to
        /// the contracts that that member has.
        /// </remarks>
        static IDictionary <string, XContract[]> GetContracts(Options options, DocTracker docTracker)
        {
            Contract.Requires(options != null);
            Contract.Requires(docTracker != null);
            Contract.Ensures(Contract.Result <IDictionary <string, XContract[]> >() != null);

            #region Establish host and load assembly

            Contract.Assume(options.resolvedPaths != null);

            var host = new CodeContractAwareHostEnvironment(options.libpaths);
            foreach (var p in options.resolvedPaths)
            {
                host.AddResolvedPath(p);
            }
            IModule module = host.LoadUnitFrom(options.assembly) as IModule;
            if (module == null || module == Dummy.Module || module == Dummy.Assembly)
            {
                Console.WriteLine("'{0}' is not a PE file containing a CLR module or assembly.", options.assembly);
                Environment.Exit(1);
            }
            #endregion
            #region Create the contracts dictionary
            Dictionary <string, XContract[]> contracts = new Dictionary <string, XContract[]>(StringComparer.Ordinal); //Use Ordinal compare for faster string comparison.
            #endregion
            #region Traverse module and extract contracts
            var contractsVisitor = new ContractVisitor(host, contracts, options, docTracker);
            var traverser        = new ContractTraverser(host);
            traverser.PreorderVisitor = contractsVisitor;
            traverser.Traverse(module);
            #endregion
            return(contracts);
        }
 /// <summary>
 /// Wraps a call to GetTypeContractFor inside of a try-catch statement.
 /// </summary>
 public static bool TryGetTypeContract(CodeContractAwareHostEnvironment host, ITypeReference type, out ITypeContract typeContract, DocTracker docTracker)
 {
     Contract.Requires(host != null);
     Contract.Requires(type != null);
     Contract.Ensures(!Contract.Result <bool>() || Contract.ValueAtReturn(out typeContract) != null);
     try {
         var unit = TypeHelper.GetDefiningUnit(type.ResolvedType);
         if (unit == null)
         {
             typeContract = null;
         }
         else
         {
             IContractProvider lcp = host.GetContractExtractor(unit.UnitIdentity);
             if (lcp == null)
             {
                 typeContract = null;
             }
             else
             {
                 typeContract = lcp.GetTypeContractFor(type);
             }
         }
     } catch (NullReferenceException) {
         docTracker.WriteLine("ERROR: NullReferenceException was thrown in CCI!");
         typeContract = null;
     }
     return(typeContract != null);
 }
 /// <summary>
 /// Creates a new contract packager.
 /// </summary>
 public ContractPackager(CodeContractAwareHostEnvironment host, DocTracker docTracker)
 {
     Contract.Requires(host != null);
     Contract.Requires(docTracker != null);
     this.host       = host;
     this.docTracker = docTracker;
 }
Exemplo n.º 4
0
 public static CodeContractAwareHostEnvironment GetInstance()
 {
     if (host == null)
     {
         host = new CodeContractAwareHostEnvironment();
     }
     return(host);
 }
        /// <summary>
        /// Creates a ContractTraverser
        /// </summary>
        /// <param name="contracts">The dictionary of contracts. This gets filled with contracts during the traversal.</param>
        /// <param name="options">The options.</param>
        /// <param name="host">The host environment of the traverser used to load any required assemblies.</param>
        /// <param name="docTracker">The DocTracker used to provide metrics and to be written into during the traversal.</param>
        public ContractVisitor(CodeContractAwareHostEnvironment host, IDictionary <string, XContract[]> contracts, Options options, DocTracker docTracker)
        {
            Contract.Requires(host != null);
            Contract.Requires(contracts != null);
            //Contract.Requires(options != null);
            Contract.Requires(docTracker != null);

            this.contracts = contracts;
            //this.options = options;
            this.docTracker = docTracker;
            this.host       = host;
        }
 /// <summary>
 /// Wraps a call to GetMethodContractFor inside of a try-catch statement.
 /// </summary>
 public static bool TryGetMethodContract(CodeContractAwareHostEnvironment host, IMethodReference method, out IMethodContract methodContract, DocTracker docTracker)
 {
     Contract.Requires(host != null);
     Contract.Requires(method != null);
     Contract.Ensures(!Contract.Result <bool>() || Contract.ValueAtReturn(out methodContract) != null);
     try {
         methodContract = ContractHelper.GetMethodContractFor(host, method.ResolvedMethod);
     } catch (NullReferenceException) {
         docTracker.WriteLine("ERROR: NullReferenceException was thrown in CCI!");
         methodContract = null;
     }
     //} catch (Exception e) {
     //  docTracker.WriteLine("ERROR: Exception of type '{0}' was thrown in CCI!", e.GetType().Name);
     //  docTracker.WriteLine("\t'{0}'", e.Message);
     //  methodContract = null;
     //}
     return(methodContract != null);
 }
Exemplo n.º 7
0
 public CciAssemblyPersister()
 {
     host = CciHostEnvironment.GetInstance();
 }
Exemplo n.º 8
0
        static int Main(string[] args)
        {
            if (args == null || args.Length == 0)
            {
                Console.WriteLine("usage: HelloContracts [path]fileName.Contracts.dll [-libpaths ...]* [-p [-i] | -inject]");
                return(1);
            }
            #region Parse options
            var options = new Options();
            options.Parse(args);
            if (options.HelpRequested)
            {
                options.PrintOptions("");
                return(1);
            }
            if (options.HasErrors)
            {
                options.PrintErrorsAndExit(Console.Out);
            }
            #endregion

            var fileName = String.IsNullOrEmpty(options.assembly) ? options.GeneralArguments[0] : options.assembly;

            if (options.printContracts)
            {
                #region Collect and write contracts
                using (var host = new CodeContractAwareHostEnvironment(options.libpaths)) {
                    IModule module = host.LoadUnitFrom(fileName) as IModule;
                    if (module == null || module is Dummy)
                    {
                        Console.WriteLine("'{0}' is not a PE file containing a CLR module or assembly.", fileName);
                        Environment.Exit(1);
                    }
                    var t = new Traverser(host, options.inherited);
                    t.Traverse(module);
                }
                #endregion
                return(0);
            }
            else
            {
                using (var host = new CodeContractAwareHostEnvironment(options.libpaths, true, true)) {
                    // Read the Metadata Model from the PE file
                    var module = host.LoadUnitFrom(fileName) as IModule;
                    if (module == null || module is Dummy)
                    {
                        Console.WriteLine(fileName + " is not a PE file containing a CLR module or assembly.");
                        return(1);
                    }

                    // Get a PDB reader if there is a PDB file.
                    PdbReader /*?*/ pdbReader = null;
                    string          pdbFile   = Path.ChangeExtension(module.Location, "pdb");
                    if (File.Exists(pdbFile))
                    {
                        using (var pdbStream = File.OpenRead(pdbFile)) {
                            pdbReader = new PdbReader(pdbStream, host);
                        }
                    }

                    using (pdbReader) {
                        ISourceLocationProvider sourceLocationProvider = pdbReader;

                        // Construct a Code Model from the Metadata model via decompilation
                        var mutableModule = Decompiler.GetCodeModelFromMetadataModel(host, module, pdbReader, DecompilerOptions.AnonymousDelegates | DecompilerOptions.Loops);
                        ILocalScopeProvider localScopeProvider = new Decompiler.LocalScopeProvider(pdbReader);

                        // Extract contracts (side effect: removes them from the method bodies)
                        var contractProvider = Microsoft.Cci.MutableContracts.ContractHelper.ExtractContracts(host, mutableModule, pdbReader, localScopeProvider);

                        // Inject non-null postconditions
                        if (options.inject)
                        {
                            new NonNullInjector(host, contractProvider).Traverse(mutableModule);
                        }

                        // Put the contracts back in as method calls at the beginning of each method
                        Microsoft.Cci.MutableContracts.ContractHelper.InjectContractCalls(host, mutableModule, contractProvider, sourceLocationProvider);

                        // Write out the resulting module. Each method's corresponding IL is produced
                        // lazily using CodeModelToILConverter via the delegate that the mutator stored in the method bodies.
                        using (var peStream = File.Create(mutableModule.Location + ".pe")) {
                            if (pdbReader == null)
                            {
                                PeWriter.WritePeToStream(mutableModule, host, peStream);
                            }
                            else
                            {
                                using (var pdbWriter = new PdbWriter(mutableModule.Location + ".pdb", sourceLocationProvider)) {
                                    PeWriter.WritePeToStream(mutableModule, host, peStream, sourceLocationProvider, localScopeProvider, pdbWriter);
                                }
                            }
                        }
                    }
                }
                return(0);
            }
        }
Exemplo n.º 9
0
 public CciContractRewriter()
 {
     host = CciHostEnvironment.GetInstance();
 }
Exemplo n.º 10
0
        public static Bpl.Program /*?*/ TranslateAssembly(List <string> assemblyNames, HeapFactory heapFactory, Options options, List <Regex> exemptionList, bool whiteList)
        {
            Contract.Requires(assemblyNames != null);
            Contract.Requires(heapFactory != null);

            var       libPaths       = options.libpaths;
            var       wholeProgram   = options.wholeProgram;
            var /*?*/ stubAssemblies = options.stub;

            var host = new CodeContractAwareHostEnvironment(libPaths != null ? libPaths : Enumerable <string> .Empty, true, true);

            Host = host;

            Bpl.CommandLineOptions.Install(new Bpl.CommandLineOptions());

            #region Assemlies to translate (via cmd line)
            modules = new List <IModule>();
            var contractExtractors = new Dictionary <IUnit, IContractProvider>();
            var pdbReaders         = new Dictionary <IUnit, PdbReader>();
            #region Load *all* of the assemblies before doing anything else so that they can all vote on unification matters
            foreach (var a in assemblyNames)
            {
                var module = host.LoadUnitFrom(a) as IModule;
                if (module == null || module == Dummy.Module || module == Dummy.Assembly)
                {
                    Console.WriteLine(a + " is not a PE file containing a CLR module or assembly, or an error occurred when loading it.");
                    Console.WriteLine("Skipping it, continuing with other input assemblies");
                    continue;
                }
                modules.Add(module);
            }
            #endregion
            #region Decompile all of the assemblies
            var decompiledModules = new List <IModule>();
            foreach (var m in modules)
            {
                PdbReader /*?*/ pdbReader = null;
                string          pdbFile   = Path.ChangeExtension(m.Location, "pdb");
                if (File.Exists(pdbFile))
                {
                    Stream pdbStream = File.OpenRead(pdbFile);
                    pdbReader = new PdbReader(pdbStream, host);
                }
                var m2 = Decompiler.GetCodeModelFromMetadataModel(host, m, pdbReader, DecompilerOptions.Unstack) as IModule;
                // The decompiler does not turn calls to Assert/Assume into Code Model nodes
                m2 = new Microsoft.Cci.MutableContracts.ContractExtractor.AssertAssumeExtractor(host, pdbReader).Rewrite(m2);
                decompiledModules.Add(m2);
                host.RegisterAsLatest(m2);
                contractExtractors.Add(m2, host.GetContractExtractor(m2.UnitIdentity));
                pdbReaders.Add(m2, pdbReader);
            }
            modules = decompiledModules;
            #endregion
            #endregion

            #region Assemblies to translate (stubs)
            if (stubAssemblies != null)
            {
                foreach (var s in stubAssemblies)
                {
                    var module = host.LoadUnitFrom(s) as IModule;
                    if (module == null || module == Dummy.Module || module == Dummy.Assembly)
                    {
                        Console.WriteLine(s + " is not a PE file containing a CLR module or assembly, or an error occurred when loading it.");
                        Console.WriteLine("Skipping it, continuing with other input assemblies");
                    }
                    PdbReader /*?*/ pdbReader = null;
                    string          pdbFile   = Path.ChangeExtension(module.Location, "pdb");
                    if (File.Exists(pdbFile))
                    {
                        Stream pdbStream = File.OpenRead(pdbFile);
                        pdbReader = new PdbReader(pdbStream, host);
                    }
                    module = Decompiler.GetCodeModelFromMetadataModel(host, module, pdbReader, DecompilerOptions.Unstack) as IModule;

                    var copier        = new CodeDeepCopier(host);
                    var mutableModule = copier.Copy(module);

                    var mscorlib = TypeHelper.GetDefiningUnit(host.PlatformType.SystemObject.ResolvedType);

                    //var mutator = new ReparentModule(host, mscorlib, mutableModule);
                    //module = mutator.Rewrite(mutableModule);
                    //modules.Add(Tuple.Create(module, pdbReader));

                    RewriteUnitReferences renamer = new RewriteUnitReferences(host, mutableModule);
                    var mscorlibAssembly          = (IAssembly)mscorlib;
                    renamer.targetAssembly           = mscorlibAssembly;
                    renamer.originalAssemblyIdentity = mscorlibAssembly.AssemblyIdentity;
                    renamer.RewriteChildren(mutableModule);
                    modules.Add((IModule)mutableModule);
                    contractExtractors.Add(module, host.GetContractExtractor(module.UnitIdentity));
                    pdbReaders.Add(module, pdbReader);
                }
            }
            #endregion

            if (modules.Count == 0)
            {
                throw new TranslationException("No input assemblies to translate.");
            }

            //var primaryModule = modules[0];
            Sink sink = new Sink(host, heapFactory, options, exemptionList, whiteList);
            TranslationHelper.tmpVarCounter = 0;

            // TODO move away, get all plugin and translators from a config file or alike
            #region Plugged translators
            List <Translator>  translatorsPlugged = new List <Translator>();
            ITranslationPlugin bctPlugin          = new BytecodeTranslatorPlugin(wholeProgram);
            Translator         bcTranslator       = bctPlugin.getTranslator(sink, contractExtractors, pdbReaders);
            translatorsPlugged.Add(bcTranslator);

            #endregion
            sink.TranslationPlugins = translatorsPlugged;

            // TODO replace the whole translation by a translator initialization and an orchestrator calling back for each element
            // TODO for the current BC translator it will possibly just implement onMetadataElement(IModule)
            // TODO refactor this away, handle priorities between plugged translators
            IOrderedEnumerable <Translator> prioritizedTranslators = translatorsPlugged.OrderBy(t => t.getPriority());
            foreach (Translator t in prioritizedTranslators)
            {
                t.initialize();
                if (t.isOneShot())
                {
                    t.TranslateAssemblies(modules);
                }
            }

            foreach (var pair in sink.delegateTypeToDelegates.Values)
            {
                CreateDispatchMethod(sink, pair.Item1, pair.Item2);
                CreateDelegateCreateMethod(sink, pair.Item1, pair.Item2);
                CreateDelegateAddMethod(sink, pair.Item1, pair.Item2);
                CreateDelegateRemoveMethod(sink, pair.Item1, pair.Item2);
            }

            // Subtyping for extern types
            if (sink.Options.typeInfo > 0)
            {
                sink.DeclareExternTypeSubtyping();
            }

            //sink.CreateIdentifierCorrespondenceTable(primaryModule.Name.Value);

            //var rc = new Bpl.ResolutionContext((Bpl.IErrorSink)null);
            //foreach (var decl in sink.TranslatedProgram.TopLevelDeclarations) {
            //  decl.Register(rc);
            //}
            //sink.TranslatedProgram.Resolve(rc);
            //var goodDecls = new List<Bpl.Declaration>();
            //var tc = new Bpl.TypecheckingContext(null);
            //foreach (var decl in sink.TranslatedProgram.TopLevelDeclarations) {
            //  var impl = decl as Bpl.Implementation;
            //  if (impl == null) {
            //    goodDecls.Add(decl);
            //    continue;
            //  }
            //  try {
            //    //var tc = new Bpl.TypecheckingContext(null);
            //    impl.Typecheck(tc);
            //    goodDecls.Add(impl);
            //  } catch {
            //    Console.WriteLine("Deleting implementation for: " + impl.Name);
            //    // nothing to do, just continue
            //  }
            //}
            //sink.TranslatedProgram.TopLevelDeclarations = goodDecls;
            return(sink.TranslatedProgram);
        }