コード例 #1
0
 public MethodTranslator(IMethodDefinition methodDefinition, MethodBody methodBody, ClassHierarchyAnalysis CHA, ControlFlowGraph cfg, Assembly assembly, ISet <Assembly> inputAssemblies)
 {
     this.methodDefinition = methodDefinition;
     this.methodBody       = methodBody;
     this.CHA             = CHA;
     this.CFG             = cfg;
     this.assembly        = assembly;
     this.inputAssemblies = inputAssemblies;
 }
コード例 #2
0
        static ClassHierarchyAnalysis CreateCHAnalysis(IMetadataHost host)
        {
            foreach (var inputFile in Settings.InputFiles)
            {
                var assembly = new Assembly(host);
                assembly.Load(inputFile);
            }
            var CHAnalysis = new ClassHierarchyAnalysis(host);

            CHAnalysis.Analyze();
            return(CHAnalysis);
        }
コード例 #3
0
 // called from Traverser
 // set in Main
 public static void TranslateAssemblies(ISet <Assembly> assemblies, ClassHierarchyAnalysis CHA)
 {
     foreach (Assembly assembly in assemblies)
     {
         foreach (IMethodDefinition methodDefinition in assembly.GetAllDefinedMethods())
         {
             if (!methodDefinition.IsExternal)
             {
                 try
                 {
                     var disassembler = new Disassembler(assembly.Host, methodDefinition, assembly.PdbReader);
                     disassembler.Execute();
                     MethodBody       mB  = disassembler.MethodBody;
                     ControlFlowGraph cfg = disassembler.ControlFlowGraph;
                     // it would be faster to do this while we do
                     // the global search for field references
                     if (Settings.MemoryModel == ProgramOptions.MemoryModelOption.Mixed)
                     {
                         ReferenceFinder reference = new ReferenceFinder();
                         reference.CollectLocalVariables(mB);
                     }
                     MethodTranslator methodTranslator = new MethodTranslator(methodDefinition, mB, CHA, cfg, assembly, assemblies);
                     // todo: improve this piece of code
                     StreamWriter streamWriter = Program.streamWriter;
                     streamWriter.WriteLine(methodTranslator.Translate());
                     Helpers.addTranslatedMethod(methodDefinition);
                 }
                 catch (InvalidOperationException ex)
                 {
                     Console.WriteLine("WARNING: Exception thrown while translating method (omitting): " + BoogieMethod.From(methodDefinition).Name);
                     if (!Settings.SilentExceptionsForMethods)
                     {
                         throw ex;
                     }
                 }
             }
         }
     }
 }
コード例 #4
0
        public void GenerateCG()
        {
            GenerateCH();

            if (!programInfo.Contains("CG_TEXT"))
            {
                var ch  = programInfo.Get <ClassHierarchy>("CH");
                var cga = new ClassHierarchyAnalysis(ch);

                cga.OnReachableMethodFound = method =>
                {
                    //GenerateIL(method);
                    GenerateTAC(method);
                };

                var roots = host.GetRootMethods();
                var cg    = cga.Analyze(host, roots);
                var text  = DGMLSerializer.Serialize(cg);

                programInfo.Add("CG_TEXT", text);
            }
        }
コード例 #5
0
        private void CallMethodData(MethodBase methodInfo, MethodData methodData, OperationKind operationKind,
                                    CrRuntimeLibrary crRuntime)
        {
            if (HandleRuntimeHelpersMethod(methodInfo))
            {
                methodData.ExtractNeededValuesFromStack(_evaluator);
                AddOperation(OperationKind.CallRuntime, methodData);
                return;
            }
            if (methodInfo.IsConstructor && methodInfo.DeclaringType == typeof(object))
            {
                return;
            }
            methodData.ExtractNeededValuesFromStack(_evaluator);

            if (!methodData.Info.IsStatic && methodData.Parameters.Count > 0)
            {
                methodData.Info = ClassHierarchyAnalysis.GetBestVirtualMatch(methodData.Info,
                                                                             methodData.Parameters[0].ComputedType().ClrType);
            }
            var declaringType = methodData.Info.DeclaringType;

            if (declaringType.IsSubclassOf(typeof(Delegate)))
            {
                var signature = declaringType.GetMethod("Invoke");
                DelegateManager.RegisterType(declaringType, signature);
            }

            if (!methodData.IsVoid)
            {
                var vreg = SetNewVReg();
                vreg.FixedType    = new TypeDescription(methodInfo.GetReturnType());
                methodData.Result = vreg;
            }
            methodData.FixedType = new TypeDescription(methodInfo.GetReturnType());
            AddOperation(operationKind, methodData);
        }
コード例 #6
0
        public static void Start(ProgramOptions programOptions)
        {
            Console.WriteLine(programOptions);
            Settings.SetProgramOptions(programOptions);
            var outputPath = SetupOutputFile();

            streamWriter.WriteLine(Resource.GetResourceAsString("TinyBCT.Resources.Prelude.bpl"));

            if (Settings.AsyncSupport || Settings.AsyncSupportGenerics)
            {
                streamWriter.WriteLine(Resource.GetResourceAsString("TinyBCT.Resources.CommonAsyncPrelude.bpl"));
            }

            if (Settings.AsyncSupport)
            {
                streamWriter.WriteLine(Resource.GetResourceAsString("TinyBCT.Resources.AsyncPrelude.bpl"));
            }

            if (Settings.AsyncSupportGenerics)
            {
                streamWriter.WriteLine(Resource.GetResourceAsString("TinyBCT.Resources.AsyncPreludeGeneric.bpl"));
            }

            using (var host = new PeReader.DefaultHost())
            {
                #region Load assemblies
                ISet <Assembly> inputAssemblies = new HashSet <Assembly>();
                foreach (string inputFile in Settings.InputFiles)
                {
                    Assembly assembly = new Assembly(host);
                    assembly.Load(inputFile);
                    inputAssemblies.Add(assembly);
                }
                #endregion

                #region Execute CHA
                var CHAnalysis = new ClassHierarchyAnalysis(host);
                CHAnalysis.Analyze();
                #endregion

                #region Initialize host types
                Types.Initialize(host);
                #endregion

                // TODO(diegog): Analysis not integrated yet
                // This can be used to obtain the allocated types and delegates
                //var allocationsAndDelelegatesAnalysis = new TypesAndDelegatesCollector(host);

                #region Write three address code for debugging
                TACWriter.WriteTAC(inputAssemblies);
                #endregion

                #region Look for references (used in mixed memory model)
                if (Settings.MemoryModel == ProgramOptions.MemoryModelOption.Mixed)
                {
                    ReferenceFinder.TraverseForFields(inputAssemblies);
                }
                #endregion

                #region Translate defined types and add axioms about subtyping
                TypeDefinitionTranslator.TranslateTypes(inputAssemblies);
                #endregion

                #region Translate defined methods
                MethodTranslator.TranslateAssemblies(inputAssemblies, CHAnalysis);
                #endregion

                #region Create main wrapper with static fields initialization and static constructors calls
                StaticInitializer.SearchStaticConstructorsAndMain(inputAssemblies);
                streamWriter.WriteLine(StaticInitializer.CreateInitializeGlobals());
                streamWriter.WriteLine(StaticInitializer.CreateMainWrappers());
                streamWriter.WriteLine(StaticInitializer.CreateStaticVariablesAllocProcedure());
                streamWriter.WriteLine(StaticInitializer.CreateDefaultValuesStaticVariablesProcedure());
                streamWriter.WriteLine(StaticInitializer.CreateStaticConstructorsCallsProcedure());
                #endregion

                #region Translate types that are referenced but not defined in the input assemblies
                TypeDefinitionTranslator.DefineUndeclaredSuperClasses();
                TypeDefinitionTranslator.ParametricTypeDeclarations();
                #endregion

                #region Translate string constants
                BoogieLiteral.Strings.WriteStringConsts(streamWriter);
                #endregion

                #region Translate delegates
                streamWriter.WriteLine(DelegateStore.DefineMethodsIdentifiers());
                streamWriter.WriteLine(DelegateStore.CreateDelegateMethod());
                streamWriter.WriteLine(DelegateStore.InvokeDelegateMethod());
                #endregion

                // CreateAllAsyncMethods(streamWriter);
                #region Heuristic to catch getters & setters. If they are in our input assemblies we generate a body using a field associated to that property
                IEnumerable <IMethodReference> usedProperties = new List <IMethodReference>();
                if (Settings.StubGettersSetters || Settings.StubGettersSettersWhitelist.Count > 0)
                {
                    GetterSetterStub getterSetterStub = new GetterSetterStub();
                    usedProperties = getterSetterStub.Stub(inputAssemblies, streamWriter);
                }
                #endregion

                #region Generate stubs for async methods
                if (Settings.AsyncSupport)
                {
                    AsyncStubs asyncStubs = new AsyncStubs(inputAssemblies);
                    streamWriter.WriteLine(asyncStubs.AsyncMethodBuilderStartStub(false));
                    streamWriter.WriteLine(asyncStubs.AsyncStubsScheduleTask(false));
                }

                if (Settings.AsyncSupportGenerics)
                {
                    AsyncStubs asyncStubs = new AsyncStubs(inputAssemblies);
                    streamWriter.WriteLine(asyncStubs.AsyncMethodBuilderStartStub(true));
                    streamWriter.WriteLine(asyncStubs.AsyncStubsScheduleTask(true));
                }

                if (!Settings.AsyncSupport && Settings.AsyncSupportGenerics)
                {
                    // this is only in AsyncSupport prelude
                    // we can't add it to AsyncSupportGenerics because we are not always sure there will be all defined types and functions

                    bool hasEventually = inputAssemblies.GetAllDefinedMethods().Any(m => m.Name.Value.Equals("Eventually"));
                    if (hasEventually)
                    {
                        AsyncStubs asyncStubs = new AsyncStubs(inputAssemblies);
                        streamWriter.WriteLine(asyncStubs.EventuallyStub());
                    }
                }

                #endregion

                streamWriter.WriteLine(StringTranslator.Stubs());

                #region Translate called methods as extern (bodyless methods or methods not present in our input assemblies)

                var externMethods = InstructionTranslator.CalledMethods.Except(inputAssemblies.GetAllDefinedMethods().Where(m => m.Body.Size > 0)).Except(usedProperties);
                externMethods = externMethods.Where(m => !StringTranslator.GetBoogieNamesForStubs().Contains(BoogieMethod.From(m).Name));
                foreach (var methodRef in externMethods)
                {
                    var head = Helpers.GetExternalMethodDefinition(Helpers.GetUnspecializedVersion(methodRef));
                    streamWriter.WriteLine(head);
                }

                #endregion

                #region Translate class fields
                // we declare read or written fields
                foreach (var field in FieldTranslator.GetFieldDefinitions())
                {
                    streamWriter.WriteLine(field);
                }
                #endregion

                streamWriter.Close();

                #region Append bpl input files
                foreach (var bplInputFile in Settings.BplInputFiles)
                {
                    var output = new FileStream(outputPath, FileMode.Append, FileAccess.Write);

                    using (var inputStream = File.OpenRead(bplInputFile))
                    {
                        inputStream.CopyTo(output);
                    }

                    output.Close();
                }
                #endregion
            }
        }
コード例 #7
0
ファイル: Helpers.cs プロジェクト: m7nu3l/TinyBCT
        public static IList <IMethodReference> PotentialCalleesUsingCHA(IMethodReference unsolvedCallee, IVariable receiver,
                                                                        MethodCallOperation operation, ClassHierarchyAnalysis CHA)
        {
            var result = new List <IMethodReference>();

            switch (operation)
            {
            case MethodCallOperation.Static:
                result.Add(unsolvedCallee);
                break;

            case MethodCallOperation.Virtual:
                //var receiver = invocation.Arguments[0];
                var type = (receiver.Type is IGenericTypeInstanceReference) ? (receiver.Type as IGenericTypeInstanceReference).GenericType : receiver.Type;
                if (type is IManagedPointerTypeReference)
                {
                    type = (type as IManagedPointerTypeReference).TargetType;
                    type = TypeHelper.UninstantiateAndUnspecialize(type);
                }
                var calleeTypes = new List <ITypeReference>(CHA.GetAllSubtypes(type));
                calleeTypes.Add(type);
                var candidateCalless  = calleeTypes.Select(t => t.FindMethodImplementationForGenerics(unsolvedCallee)).Where(t => t != null);
                var candidateCalless2 = calleeTypes.Select(t => t.FindMethodImplementation(unsolvedCallee)).Where(t => t != null);
                candidateCalless = candidateCalless.Union(candidateCalless2);
                foreach (var candidate in candidateCalless)     // improved this
                {
                    if (!result.Contains(candidate))
                    {
                        result.Add(candidate);
                    }
                }
                break;
            }

            result.Sort(new SubtypeComparer()); // improved this
            return(result);
        }
コード例 #8
0
        public static string Serialize(ClassHierarchyAnalysis ch)
        {
            using (var stringWriter = new StringWriter())
                using (var xmlWriter = new XmlTextWriter(stringWriter))
                {
                    var allDefinedTypes = new Dictionary <ITypeReference, int>(new TypeDefinitionComparer());

                    xmlWriter.Formatting = Formatting.Indented;
                    xmlWriter.WriteStartElement("DirectedGraph");
                    xmlWriter.WriteAttributeString("xmlns", "http://schemas.microsoft.com/vs/2009/dgml");
                    xmlWriter.WriteStartElement("Nodes");

                    foreach (var type in ch.Types)
                    {
                        allDefinedTypes.Add(type, allDefinedTypes.Count);
                    }

                    foreach (var entry in allDefinedTypes)
                    {
                        var nodeId = Convert.ToString(entry.Value);
                        var label  = TypeHelper.GetTypeName(entry.Key);

                        xmlWriter.WriteStartElement("Node");
                        xmlWriter.WriteAttributeString("Id", nodeId);
                        xmlWriter.WriteAttributeString("Label", label);
                        xmlWriter.WriteEndElement();
                    }

                    xmlWriter.WriteEndElement();
                    xmlWriter.WriteStartElement("Links");

                    foreach (var entry in allDefinedTypes)
                    {
                        var sourceId = Convert.ToString(entry.Value);
                        var subtypes = ch.GetSubtypes(entry.Key);

                        foreach (var subtype in subtypes)
                        {
                            var subtypeId = allDefinedTypes[subtype];
                            var targetId  = Convert.ToString(subtypeId);

                            xmlWriter.WriteStartElement("Link");
                            xmlWriter.WriteAttributeString("Source", sourceId);
                            xmlWriter.WriteAttributeString("Target", targetId);
                            xmlWriter.WriteEndElement();
                        }
                    }

                    xmlWriter.WriteEndElement();
                    xmlWriter.WriteStartElement("Styles");
                    xmlWriter.WriteStartElement("Style");
                    xmlWriter.WriteAttributeString("TargetType", "Node");

                    xmlWriter.WriteStartElement("Setter");
                    xmlWriter.WriteAttributeString("Property", "FontFamily");
                    xmlWriter.WriteAttributeString("Value", "Consolas");
                    xmlWriter.WriteEndElement();

                    xmlWriter.WriteStartElement("Setter");
                    xmlWriter.WriteAttributeString("Property", "NodeRadius");
                    xmlWriter.WriteAttributeString("Value", "5");
                    xmlWriter.WriteEndElement();

                    xmlWriter.WriteStartElement("Setter");
                    xmlWriter.WriteAttributeString("Property", "MinWidth");
                    xmlWriter.WriteAttributeString("Value", "0");
                    xmlWriter.WriteEndElement();

                    xmlWriter.WriteEndElement();
                    xmlWriter.WriteEndElement();
                    xmlWriter.WriteEndElement();
                    xmlWriter.Flush();
                    return(stringWriter.ToString());
                }
        }
コード例 #9
0
ファイル: Traverser.cs プロジェクト: michael-emmi/TinyBCT
        public static ControlFlowGraph CFG; // ugly - the thing is that if labels were erased we can't create cfg

        public Traverser(IMetadataHost host, ISourceLocationProvider sourceLocationProvider, ClassHierarchyAnalysis CHAnalysis)
        {
            this.host = host;
            this.sourceLocationProvider = sourceLocationProvider;
            CHA = CHAnalysis;
        }
コード例 #10
0
 public MethodTranslator(IMethodDefinition methodDefinition, MethodBody methodBody, ClassHierarchyAnalysis CHA)
 {
     this.methodDefinition = methodDefinition;
     this.methodBody       = methodBody;
     this.CHA = CHA;
 }
コード例 #11
0
ファイル: Helpers.cs プロジェクト: michael-emmi/TinyBCT
        public static IList <IMethodReference> PotentialCalleesUsingCHA(IMethodReference unsolvedCallee, IVariable receiver,
                                                                        MethodCallOperation operation, ClassHierarchyAnalysis CHA)
        {
            var result = new List <IMethodReference>();

            // var unsolvedCallee = invocation.Method;
            if (unsolvedCallee.Name.Value.Contains("GetEnumerator"))
            {
            }
            switch (operation)
            {
            case MethodCallOperation.Static:
                result.Add(unsolvedCallee);
                break;

            case MethodCallOperation.Virtual:
                //var receiver = invocation.Arguments[0];
                var type = (receiver.Type is IGenericTypeInstanceReference) ? (receiver.Type as IGenericTypeInstanceReference).GenericType : receiver.Type;
                if (type is IManagedPointerTypeReference)
                {
                    type = (type as IManagedPointerTypeReference).TargetType;
                    type = TypeHelper.UninstantiateAndUnspecialize(type);
                    //type = (type is IGenericTypeInstanceReference) ? (type as IGenericTypeInstanceReference).GenericType : type;
                }
                var calleeTypes = new List <ITypeReference>(CHA.GetAllSubtypes(type));
                //// Hack to get the type from CollectionStubs
                //var typeCHA = CHA.Types.SingleOrDefault(t => t.ToString() == type.ToString());
                //if (typeCHA != null)
                //    type = typeCHA;

                calleeTypes.Add(type);
                var candidateCalless  = calleeTypes.Select(t => t.FindMethodImplementationForGenerics(unsolvedCallee)).Where(t => t != null);
                var candidateCalless2 = calleeTypes.Select(t => t.FindMethodImplementation(unsolvedCallee)).Where(t => t != null);
                candidateCalless = candidateCalless.Union(candidateCalless2);
                foreach (var candidate in candidateCalless)     // improved this
                {
                    if (!result.Contains(candidate))
                    {
                        result.Add(candidate);
                    }
                }
                //result.AddRange(candidateCalless);
                break;
            }

            result.Sort(new SubtypeComparer()); // improved this
            return(result);
        }