// // You can use the following additional attributes as you write your tests: // // Use ClassInitialize to run code before running the first test in the class // [ClassInitialize()] // public static void MyClassInitialize(TestContext testContext) { } // // Use ClassCleanup to run code after all tests in a class have run // [ClassCleanup()] // public static void MyClassCleanup() { } // // Use TestInitialize to run code before running each test // [TestInitialize()] // public void MyTestInitialize() { } // // Use TestCleanup to run code after each test has run // [TestCleanup()] // public void MyTestCleanup() { } // #endregion private string ExecuteTest(string assemblyName, HeapFactory heapFactory) { var options = new Options(); options.monotonicHeap = true; options.dereference = Options.Dereference.Assume; BCT.TranslateAssemblyAndWriteOutput(new List<string> { assemblyName }, heapFactory, options, null, false); var fileName = Path.ChangeExtension(assemblyName, "bpl"); var s = File.ReadAllText(fileName); return s; }
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; }
static int Main(string[] args) { int errorReturnValue = -1; #region Parse options and check for errors var options = new Options(); options.Parse(args); if (options.HelpRequested) { options.PrintOptions(""); return errorReturnValue; } if (options.HasErrors) { options.PrintErrorsAndExit(Console.Out); } if (!String.IsNullOrWhiteSpace(options.exemptionFile)) { string fileName = options.exemptionFile; var c = fileName[fileName.Length - 1]; if (c == '+' || c == '-') fileName = options.exemptionFile.Remove(fileName.Length - 1); if (!File.Exists(fileName)) { Console.WriteLine("Specified exemption file '{0}' not found.", fileName); } } if (options.stub != null) { Console.WriteLine("/s is no longer used to specify stub assemblies"); return errorReturnValue; } if (options.modelExceptions == 1 && !options.wholeProgram) { Console.WriteLine("can specify a precise modeling of exceptions only when doing whole program analysis"); return errorReturnValue; } if (options.breakIntoDebugger) { System.Diagnostics.Debugger.Launch(); } #endregion var assemblyNames = options.assemblies; if (assemblyNames == null || assemblyNames.Count == 0) { assemblyNames = new List<string>(); foreach (var g in options.GeneralArguments) { assemblyNames.Add(g); } } #region If an exclusion file has been specified, read in each line as a regular expression List<Regex> exemptionList = null; bool whiteList = false; if (!String.IsNullOrWhiteSpace(options.exemptionFile)) { int i = 0; exemptionList = new List<Regex>(); string fileName = options.exemptionFile; var c = fileName[fileName.Length - 1]; whiteList = true; if (c == '+' || c == '-') { fileName = options.exemptionFile.Remove(fileName.Length - 1); if (c == '-') whiteList = false; } try { // Create an instance of StreamReader to read from a file. // The using statement also closes the StreamReader. using (StreamReader sr = new StreamReader(fileName)) { String line; // Read and display lines from the file until the end of // the file is reached. while ((line = sr.ReadLine()) != null) { exemptionList.Add(new Regex(line)); i++; } //Console.WriteLine("Read {0} lines from the exclusion file '{1}'.", // i, options.exemptionFile); } } catch (Exception e) { Console.WriteLine("Something went wrong reading the exclusion file '{0}'; read in {1} lines, continuing processing.", fileName, i); Console.WriteLine(e.Message); } } #endregion try { HeapFactory heap; switch (options.heapRepresentation) { case Options.HeapRepresentation.splitFields: heap = new SplitFieldsHeap(); break; case Options.HeapRepresentation.general: heap = new GeneralHeap(); break; default: Console.WriteLine("Unknown setting for /heap"); return 1; } if ((options.phoneFeedbackCode || options.phoneNavigationCode) && (options.phoneControls == null || options.phoneControls == "")) { Console.WriteLine("Options /phoneNavigationCode and /phoneFeedbackCode need /phoneControls option set."); return 1; } var pgm = TranslateAssembly(assemblyNames, heap, options, exemptionList, whiteList); var fileName = assemblyNames[0]; fileName = Path.GetFileNameWithoutExtension(fileName); string outputFileName = fileName + ".bpl"; // Microsoft.Boogie.TokenTextWriter writer = new Microsoft.Boogie.TokenTextWriter("_" + outputFileName); Microsoft.Boogie.TokenTextWriter writer = new Microsoft.Boogie.TokenTextWriter(outputFileName); Prelude.Emit(writer); pgm.Emit(writer); writer.Close(); return 0; // return Inline(outputFileName); } catch (Exception e) { // swallow everything and just return an error code Console.WriteLine("The byte-code translator failed: {0}", e.Message); // Console.WriteLine("Stack trace: {0}", e.StackTrace); return -1; } }
public static int TranslateAssemblyAndWriteOutput(List<string> assemblyNames, HeapFactory heapFactory, Options options, List<Regex> exemptionList, bool whiteList) { Contract.Requires(assemblyNames != null); Contract.Requires(heapFactory != null); try { var pgm = TranslateAssembly(assemblyNames, heapFactory, options, exemptionList, whiteList); var fileName = assemblyNames[0]; fileName = Path.GetFileNameWithoutExtension(fileName); string outputFileName = fileName + ".bpl"; using (var writer = new Microsoft.Boogie.TokenTextWriter(outputFileName)) { Prelude.Emit(writer); pgm.Emit(writer); writer.Close(); } return 0; // success } catch (Exception e) { // swallow everything and just return an error code Console.WriteLine("The byte-code translator failed: {0}", e.Message); // Console.WriteLine("Stack trace: {0}", e.StackTrace); return -1; } }