public MemoryVisitor(CodeContractAwareHostEnvironment host, PdbReader pdbReader, ContractProvider contractProvider, MemoryContractsInformation memoryContractsInformation, PointsToInformation pointsToInformation) { _host = host; _pdbReader = pdbReader; _contractProvider = contractProvider; _memoryContractsInformation = memoryContractsInformation; _errorReportItems = new List<ErrorReportItem>(); _pointsToInformation = pointsToInformation; }
/// <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> /// 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; }
/// <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; }
/// <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; }
private static MemoryContractsInformation ExtractMemoryContractsFromModule(CodeContractAwareHostEnvironment host, IModule module) { var memoryContractsInformation = new MemoryContractsInformation(); if (_visitedModules.Contains(module)) { return memoryContractsInformation; } _visitedModules.Add(module); if (module != null && module != Dummy.Module && module != Dummy.Assembly) { 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); } } module = Decompiler.GetCodeModelFromMetadataModel(host, module, pdbReader); var extractor = new MemoryContractsExtractor(); extractor.Visit(module); memoryContractsInformation.MethodsTmpTypes = extractor.MethodsTmpTypes; memoryContractsInformation.MethodsTmpContracts = extractor.MethodsTmpContracts; memoryContractsInformation.MethodsTmpContractsWithConds = extractor.MethodsTmpContractsWithConds; memoryContractsInformation.MethodsRsdTypes = extractor.MethodsRsdTypes; memoryContractsInformation.MethodsRsdContracts = extractor.MethodsRsdContracts; memoryContractsInformation.MethodsRsdContractsWithConds = extractor.MethodsRsdContractsWithConds; memoryContractsInformation.MethodsRsdExprs = extractor.MethodsRsdExprs; //merge the contracts of the referenced assemblies foreach (var assemblyReference in module.AssemblyReferences) { //skip assemblies that we know don't have memory contracts if (!new List<string>() { "mscorlib", "Contracts", "System", "Microsoft" }.Exists(s => assemblyReference.Name.Value.StartsWith(s))) { var referencedAssembly = host.LoadAssembly(assemblyReference.AssemblyIdentity); var referencedModuleMemoryContractsInformation = ExtractMemoryContractsFromModule(host, referencedAssembly); if (referencedModuleMemoryContractsInformation.MethodsTmpTypes != null) { foreach (var methodName in referencedModuleMemoryContractsInformation.MethodsTmpTypes.Keys) { memoryContractsInformation.MethodsTmpTypes[methodName] = referencedModuleMemoryContractsInformation.MethodsTmpTypes[methodName]; } } if (referencedModuleMemoryContractsInformation.MethodsRsdTypes != null) { foreach (var methodName in referencedModuleMemoryContractsInformation.MethodsRsdTypes.Keys) { memoryContractsInformation.MethodsRsdTypes[methodName] = referencedModuleMemoryContractsInformation.MethodsRsdTypes[methodName]; } } } } } return memoryContractsInformation; }
private static MemoryContractsInformation ExtractMemoryContracts(CodeContractAwareHostEnvironment host, string assemblyFullPath) { var module = host.LoadUnitFrom(assemblyFullPath) as IModule; return ExtractMemoryContractsFromModule(host, module); }
private static List<ErrorReportItem> RewriteAssembly(CodeContractAwareHostEnvironment host, string assemblyFullPath, MemoryContractsInformation memoryContractsInformation, PointsToInformation pointsToInformation) { var module = host.LoadUnitFrom(assemblyFullPath) as IModule; 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); } } if (module != null && module != Dummy.Module && module != Dummy.Assembly) { var mutableModule = Decompiler.GetCodeModelFromMetadataModel(host, module, pdbReader); using (pdbReader) { var contractProvider = Microsoft.Cci.MutableContracts.ContractHelper.ExtractContracts(host, mutableModule, pdbReader, pdbReader); var mutator = new MemoryVisitor(host, pdbReader, contractProvider, memoryContractsInformation, pointsToInformation); mutator.Visit(mutableModule); Microsoft.Cci.MutableContracts.ContractHelper.InjectContractCalls(host, mutableModule, contractProvider, pdbReader); Stream peStream = File.Create(Path.ChangeExtension(mutableModule.Location, ".mod.dll")); if (pdbReader == null) { PeWriter.WritePeToStream(mutableModule, host, peStream); } else { using (var pdbWriter = new PdbWriter(Path.ChangeExtension(pdbFile, ".mod.pdb"), pdbReader)) { PeWriter.WritePeToStream(mutableModule, host, peStream, pdbReader, pdbReader, pdbWriter); } } peStream.Close(); return mutator.ErrorReportItems; } } return null; }
static int Main(string[] args) { //for debugging //args = new string[] { @"C:\Users\Jonathan Tapicer\Desktop\tesis\cci_rewriter\example_with_contracts\Example\obj\Debug\Decl\Example.dll", @"C:\Users\Jonathan Tapicer\Desktop\tesis\cci_rewriter\Contracts.Contract.Memory\;C:\Program Files (x86)\Microsoft\Contracts\PublicAssemblies\v3.5\;C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\;C:\Windows\Microsoft.NET\Framework\v2.0.50727\;C:\Users\Jonathan Tapicer\Desktop\tesis\cci_rewriter\Contracts.Contract.Memory\CodeContracts;C:\Program Files (x86)\Microsoft\Contracts\PublicAssemblies\v3.5\CodeContracts;C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\CodeContracts;C:\Windows\Microsoft.NET\Framework\v2.0.50727\CodeContracts;C:\Program Files (x86)\Microsoft\Contracts\Contracts\v3.5" }; //args = new string[] { @"C:\Users\Jonathan Tapicer\Desktop\tesis\cci_rewriter\example_with_contracts_Person\PersonExample\obj\Debug\Decl\PersonExample.dll" }; //args = new string[] { @"C:\Users\Jonathan Tapicer\Desktop\tesis\cci_rewriter\experiments\experiments\obj\Debug\Decl\experiments.dll" }; //args = new string[] { @"C:\Users\Jonathan Tapicer\Desktop\tesis\cci_rewriter\example_cross_assembly\Assembly1\obj\Debug\Decl\Assembly1.dll", @"C:\Users\Jonathan Tapicer\Desktop\tesis\cci_rewriter\example_cross_assembly\Assembly2\bin\Debug\;C:\Users\Jonathan Tapicer\Desktop\tesis\cci_rewriter\Contracts.Contract.Memory\;C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\;C:\Users\Jonathan Tapicer\Desktop\tesis\cci_rewriter\example_cross_assembly\Assembly2\bin\Debug\CodeContracts;C:\Users\Jonathan Tapicer\Desktop\tesis\cci_rewriter\Contracts.Contract.Memory\CodeContracts;C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\CodeContracts;C:\Program Files (x86)\Microsoft\Contracts\Contracts\.NETFramework\v4.0" }; //args = new string[] { @"C:\TESIS\tesis\cci_rewriter\example_with_contracts_Person\PersonExample\obj\Debug\Decl\PersonExample.dll", @"C:\TESIS\tesis\cci_rewriter\Contracts.Contract.Memory\;C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\;C:\TESIS\tesis\cci_rewriter\Contracts.Contract.Memory\CodeContracts;C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\CodeContracts;C:\Program Files\Microsoft\Contracts\Contracts\.NETFramework\v4.0" }; if (args.Length < 1) { Console.WriteLine("Usage: memory_contracts_rewriter.exe [assembly_full_path] [lib_paths]"); return 1; } var assemblyFullPath = args[0]; var libPaths = new string[0]; if (args.Length > 1) { libPaths = args[1].Split(Path.PathSeparator); } try { var host = new CodeContractAwareHostEnvironment(libPaths, true, true); var hasMemoryContracts = false; var module = host.LoadUnitFrom(assemblyFullPath) as IModule; foreach (var assemblyReference in module.AssemblyReferences) { if (assemblyReference.Name.Value == "Contracts") { hasMemoryContracts = true; break; } } if (hasMemoryContracts) { var memoryContractsInformation = ExtractMemoryContracts(host, assemblyFullPath); var pointsToInformation = new PointsToInformation(assemblyFullPath); List<ErrorReportItem> errorReportItems = RewriteAssembly(host, assemblyFullPath, memoryContractsInformation, pointsToInformation); if (errorReportItems != null) { foreach (var errorReportItem in errorReportItems) { Console.WriteLine("OutputError,{0},,,false,False,False,error,{1}", errorReportItem.Message, errorReportItem.Location); } } } else { return 2; } } catch (Exception e) { Console.WriteLine(e); return 1; } return 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; }
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 phoneControlsConfigFile = options.phoneControls; var doPhoneNav = options.phoneNavigationCode; var doPhoneFeedback = options.phoneFeedbackCode; 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); if (phoneControlsConfigFile != null && phoneControlsConfigFile != "") { // TODO this should be part of the translator initialziation PhoneCodeHelper.initialize(host); PhoneCodeHelper.instance().PhonePlugin = new PhoneControlsPlugin(phoneControlsConfigFile); if (doPhoneNav) { // TODO this should be part of the translator initialziation PhoneCodeHelper.instance().PhoneNavigationToggled = true; ITranslationPlugin phoneInitPlugin = new PhoneInitializationPlugin(); ITranslationPlugin phoneNavPlugin = new PhoneNavigationPlugin(); Translator phInitTranslator = phoneInitPlugin.getTranslator(sink, contractExtractors, pdbReaders); Translator phNavTranslator = phoneNavPlugin.getTranslator(sink, contractExtractors, pdbReaders); translatorsPlugged.Add(phInitTranslator); translatorsPlugged.Add(phNavTranslator); } if (doPhoneFeedback) { // TODO this should be part of the translator initialziation PhoneCodeHelper.instance().PhoneFeedbackToggled = true; ITranslationPlugin phoneFeedbackPlugin = new PhoneFeedbackPlugin(); Translator phFeedbackTranslator = phoneFeedbackPlugin.getTranslator(sink, contractExtractors, pdbReaders); translatorsPlugged.Add(phFeedbackTranslator); } } #endregion sink.TranslationPlugins = translatorsPlugged; /* if (phoneControlsConfigFile != null && phoneControlsConfigFile != "") { // TODO send this all way to initialization of phone plugin translator PhoneCodeHelper.initialize(host); PhoneCodeHelper.instance().PhonePlugin = new PhoneControlsPlugin(phoneControlsConfigFile); // TODO these parameters will eventually form part of plugin configuration if (doPhoneNav) { PhoneCodeHelper.instance().PhoneNavigationToggled = true; PhoneInitializationMetadataTraverser initTr = new PhoneInitializationMetadataTraverser(host); initTr.InjectPhoneCodeAssemblies(modules); PhoneNavigationMetadataTraverser navTr = new PhoneNavigationMetadataTraverser(host); navTr.InjectPhoneCodeAssemblies(modules); } if (doPhoneFeedback) { PhoneCodeHelper.instance().PhoneFeedbackToggled = true; PhoneControlFeedbackMetadataTraverser fbMetaDataTraverser= new PhoneControlFeedbackMetadataTraverser(host); fbMetaDataTraverser.Visit(modules); } } */ // 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(); string outputFileName = primaryModule.Name + ".bpl"; callPostTranslationTraversers(modules, sink, phoneControlsConfigFile, outputFileName); if (PhoneCodeHelper.instance().PhoneNavigationToggled) { finalizeNavigationAnalysisAndBoogieCode(phoneControlsConfigFile, sink, outputFileName); } //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; }