コード例 #1
0
        public static string CreateInitializeGlobals()
        {
            StringBuilder sb
                = new StringBuilder();

            sb.AppendLine("procedure {:ProgramInitialization} $initialize_globals()");
            sb.AppendLine("{");
            sb.AppendLine("\t//this procedure initializes global exception variables and calls static constructors");
            sb.AppendLine("\t$Exception := null;");
            sb.AppendLine("\t$ExceptionType := null;");
            sb.AppendLine("\t$ExceptionInCatchHandler := null;");
            sb.AppendLine("\t$ExceptionInCatchHandlerType := null;");

            foreach (var staticConstructor in staticConstructors)
            {
                var signature = BoogieMethod.From(staticConstructor).Name;
                sb.AppendLine(String.Format("\tcall {0}();", signature));
                sb.AppendLine("\tif ($Exception != null)");
                sb.AppendLine("\t{");
                sb.AppendLine("\t\treturn;");
                sb.AppendLine("\t}");
            }

            sb.AppendLine("}");
            return(sb.ToString());
        }
コード例 #2
0
ファイル: Helpers.cs プロジェクト: m7nu3l/TinyBCT
 public static Boolean IsCurrentlyMissing(IMethodReference methodReference)
 {
     // The value of this condition can change throughout the execution of the translation.
     // For that reason, it should be called at the end of the translation again to confirm
     // the method is actually missing from the binary.
     return(!methodsTranslated.Contains(BoogieMethod.From(methodReference).Name));
 }
コード例 #3
0
        public static void CreateAsyncStartMethod(StreamWriter sw)
        {
            StatementList stmts = new StatementList();

            var boogieGetTypeRes = BoogieVariable.GetTempVar(Helpers.ObjectType(), null /* need dict with used var names*/, prefix: "asyncType");
            var stateMachineVar  = BoogieVariable.GetTempVar(Helpers.ObjectType(), null /* need dict with used var names*/, prefix: "stateMachineCopy");

            stmts.Add(BoogieStatement.VariableDeclaration(stateMachineVar));
            stmts.Add(BoogieStatement.VariableDeclaration(boogieGetTypeRes));
            stmts.Add(BoogieStatement.FromString($"{stateMachineVar.Expr} := stateMachine;"));
            foreach (var asyncMethod in Helpers.asyncMoveNexts)
            {
                var asyncType = asyncMethod.ContainingTypeDefinition;
                var bg        = BoogieGenerator.Instance();
                stmts.Add(bg.ProcedureCall(BoogieMethod.GetTypeMethod, new List <Expression> {
                    stateMachineVar
                }, boogieGetTypeRes));
                StatementList ifStmts = new StatementList();
                ifStmts.Add(BoogieGenerator.Instance().ProcedureCall(BoogieMethod.From(asyncMethod), new List <Expression> {
                    stateMachineVar
                }));

                stmts.Add(BoogieStatement.If(Expression.Subtype(boogieGetTypeRes, asyncType), ifStmts));
            }
            stmts.Add(BoogieStatement.FromString($"v0$out := {stateMachineVar.Expr};"));

            sw.WriteLine(@"procedure {:extern} System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.Start``1$``0$(this : Ref,stateMachine : Ref) returns (v0$out : Ref) {");
            foreach (var stmt in stmts)
            {
                sw.WriteLine(stmt.Stmt);
            }
            sw.WriteLine("}");
        }
コード例 #4
0
        public static string CreateMainWrappers()
        {
            StringBuilder sb
                = new StringBuilder();

            foreach (var mainMethodTuple in mainMethods)
            {
                var mainMethod   = mainMethodTuple.Item1;
                var assembly     = mainMethodTuple.Item2;
                var disassembler = new Disassembler(assembly.Host, mainMethod, assembly.PdbReader);
                disassembler.Execute();
                var methodName = BoogieMethod.From(mainMethod).Name;
                var parameters = Helpers.GetParametersWithBoogieType(disassembler.MethodBody.Parameters);
                var returnType = Helpers.GetMethodBoogieReturnType(mainMethod).Equals(Helpers.BoogieType.Void) ? String.Empty : ("returns ($result :" + Helpers.GetMethodBoogieReturnType(mainMethod) + ")");
                sb.AppendLine(String.Format("procedure {{:entrypoint}} $Main_Wrapper_{0}({1}) {2}", methodName, parameters, returnType));
                sb.AppendLine("{");

                var variables = String.Empty;
                IMethodDefinition methodDef = mainMethod as IMethodDefinition;
                if (methodDef != null)
                {
                    variables = String.Join(",", methodDef.Parameters.Select(v => v.Name));
                }
                else
                {
                    variables = String.Join(",", mainMethod.Parameters.Select(v => String.Format("param{0}", v.Index)));
                }

                if (mainMethod.CallingConvention.HasFlag(Microsoft.Cci.CallingConvention.HasThis))
                {
                    variables = String.Format("this", mainMethod.ParameterCount > 0 ? "," : String.Empty, parameters);
                }

                variables = Helpers.Strings.NormalizeStringForCorral(variables);

                sb.AppendLine("\tcall $allocate_static_fields();");
                sb.AppendLine("\tcall $default_values_static_fields();");
                sb.AppendLine("\tcall $initialize_globals();");
                sb.AppendLine("\tcall $call_static_constructors();");
                if (String.IsNullOrEmpty(returnType))
                {
                    sb.AppendLine(String.Format("\tcall {0}({1});", methodName, variables));
                }
                else
                {
                    sb.AppendLine(String.Format("\tcall $result := {0}({1});", methodName, variables));
                }

                sb.AppendLine("\tif ($Exception != null)");
                sb.AppendLine("\t{");
                sb.AppendLine("\t\treturn;");
                sb.AppendLine("\t}");

                sb.AppendLine("}");
            }

            return(sb.ToString());
        }
コード例 #5
0
ファイル: Helpers.cs プロジェクト: michael-emmi/TinyBCT
        public static String GetExternalMethodDefinition(IMethodReference methodRef)
        {
            var methodName = BoogieMethod.From(methodRef).Name;

            if (Helpers.IsCurrentlyMissing(methodRef))
            {
                // TODO(rcastano): Add logger. Print this as INFO or WARNING level.
                Console.WriteLine("WARNING: Creating non-deterministic definition for missing method: " + methodName);
            }
            var parameters = Helpers.GetParametersWithBoogieType(methodRef);
            var returnType = String.Empty;

            if (Settings.NewAddrModelling)
            {
                #region Return variables in NewAddrModelling. We should only add the return variable type from CCI
                if (Helpers.GetMethodBoogieReturnType(methodRef).Equals(Helpers.BoogieType.Void))
                {
                    returnType = "returns ()";
                }
                else
                {
                    var returnVariables = new List <String>();
                    returnVariables.Add(String.Format("$result : {0}", Helpers.GetMethodBoogieReturnType(methodRef)));
                    returnType = String.Format("returns ({0})", String.Join(",", returnVariables));
                }
                #endregion
            }
            else
            {
                #region Return variables in old memory model. We need to add 'ref' parameters as return variables (in addition to the return variable from CCI).
                if (Helpers.GetMethodBoogieReturnType(methodRef).Equals(Helpers.BoogieType.Void))
                {
                    if (methodRef.Parameters.Any(p => p.IsByReference))
                    {
                        var returnVariables = new List <String>();
                        returnVariables = methodRef.Parameters.Where(p => p.IsByReference).Select(p => String.Format("v{0}$out : {1}", p.Index, Helpers.GetBoogieType(p))).ToList();
                        returnType      = String.Format("returns ({0})", String.Join(",", returnVariables));
                    }
                }
                else
                {
                    var returnVariables = new List <String>();
                    returnVariables = methodRef.Parameters.Where(p => p.IsByReference).Select(p => String.Format("v{0}$out : {1}", p.Index, Helpers.GetBoogieType(p))).ToList();
                    returnVariables.Add(String.Format("$result : {0}", Helpers.GetMethodBoogieReturnType(methodRef)));
                    returnType = String.Format("returns ({0})", String.Join(",", returnVariables));
                }
                #endregion
            }

            var t = new BoogieProcedureTemplate(methodName, " {:extern} ", StatementList.Empty, StatementList.Empty, parameters, returnType, true);

            return(t.TransformText());
        }
コード例 #6
0
ファイル: GetterSetterStubs.cs プロジェクト: m7nu3l/TinyBCT
        public string SetProcedureStub(IMethodReference method)
        {
            FieldTranslator field      = new FieldTranslator();
            var             boogieName = field.BoogieNameForField(method.ContainingType, GetFieldName(method));
            var             paramType  = Helpers.GetBoogieType(method.Parameters.ElementAt(0));

            var get = new StatementList();

            get.Add(BoogieStatement.FromString(boogieName + "[obj] := " + "val;"));

            var t = new BoogieProcedureTemplate(BoogieMethod.From(method).Name, "", StatementList.Empty, get, "obj : Ref, val : " + paramType, String.Empty, false);

            return(t.TransformText());
        }
コード例 #7
0
ファイル: GetterSetterStubs.cs プロジェクト: m7nu3l/TinyBCT
        public string GetProcedureStub(IMethodReference method)
        {
            FieldTranslator field      = new FieldTranslator();
            var             boogieName = field.BoogieNameForField(method.ContainingType, GetFieldName(method));
            var             boogieType = Helpers.GetBoogieType(method.Type);

            var get = new StatementList();

            get.Add(BoogieStatement.FromString("$result := " + boogieName + "[obj];"));

            var t = new BoogieProcedureTemplate(BoogieMethod.From(method).Name, "", StatementList.Empty, get, "obj : Ref", String.Format(" returns  ( $result : {0})", boogieType.ToString()), false);

            return(t.TransformText());
        }
コード例 #8
0
        public String Translate()
        {
            // instructions must be translated before local variables
            // modification to local variables can ocurr while instruction translation is done
            // for example when delegate creation is detected some local variables are deleted.
            var ins                 = TranslateInstructions(out Dictionary <string, BoogieVariable> temporalVariables);
            var localVariables      = TranslateLocalVariables(temporalVariables);
            var methodName          = BoogieMethod.From(methodDefinition).Name;
            var attr                = TranslateAttr();
            var parametersWithTypes = Helpers.GetParametersWithBoogieType(methodDefinition);
            var returnTypeIfAny     = TranslateReturnTypeIfAny();

            var boogieProcedureTemplate = new BoogieProcedureTemplate(methodName, attr, localVariables, ins, parametersWithTypes, returnTypeIfAny, Helpers.IsExternal(methodDefinition));

            return(boogieProcedureTemplate.TransformText());
        }
コード例 #9
0
ファイル: Helpers.cs プロジェクト: m7nu3l/TinyBCT
        // workaround
        public static Boolean IsExternal(IMethodDefinition methodDefinition)
        {
            if (methodDefinition.IsConstructor)
            {
                var methodName = BoogieMethod.From(methodDefinition).Name;
                if (methodName.Equals("System.Object.#ctor"))
                {
                    return(true);
                }
            }

            if (methodDefinition.IsExternal)
            {
                return(true);
            }

            return(false);
        }
コード例 #10
0
        public static string CreateStaticConstructorsCallsProcedure()
        {
            StatementList body = new StatementList();

            foreach (var staticConstructor in staticConstructors)
            {
                var ctor = BoogieMethod.From(staticConstructor);
                body.Add(BoogieGenerator.Instance().ProcedureCall(ctor, new List <Expression>(), null));
            }

            string        procedureName       = "$call_static_constructors";
            string        attributes          = String.Empty;
            StatementList localVariables      = new StatementList();
            String        parametersWithTypes = String.Empty;
            String        returnTypeIfAny     = String.Empty;

            BoogieProcedureTemplate temp = new BoogieProcedureTemplate(procedureName, attributes, localVariables, body, parametersWithTypes, returnTypeIfAny, false);

            return(temp.TransformText());
        }
コード例 #11
0
        private StatementList Invoke(IMethodDefinition member, BoogieVariable receiver)
        {
            Expression receiverObject = receiver;

            if (receiver.Type.Equals(Helpers.BoogieType.Addr))
            {
                AddressExpression addrExpr = new AddressExpression(member.ContainingType, receiver);
                receiverObject = BoogieGenerator.Instance().ReadAddr(addrExpr);
            }

            Expression subtype = Expression.Subtype(Expression.DynamicType(receiverObject), member.ContainingType);

            StatementList     body         = new StatementList();
            List <Expression> argumentList = new List <Expression>();

            argumentList.Add(receiverObject);
            body.Add(BoogieGenerator.Instance().ProcedureCall(BoogieMethod.From(member), argumentList));
            body.Add(BoogieStatement.ReturnStatement);
            var ifExpr = BoogieStatement.If(subtype, body);

            return(ifExpr);
        }
コード例 #12
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;
                     }
                 }
             }
         }
     }
 }
コード例 #13
0
ファイル: Helpers.cs プロジェクト: m7nu3l/TinyBCT
 public static void addTranslatedMethod(IMethodDefinition methodDefinition)
 {
     methodsTranslated.Add(BoogieMethod.From(methodDefinition).Name);
 }
コード例 #14
0
ファイル: GetterSetterStubs.cs プロジェクト: m7nu3l/TinyBCT
        // this method returns all method references that have been stubbed
        public IEnumerable <IMethodReference> Stub(ISet <Assembly> inputAssemblies, StreamWriter streamWriter)
        {
            PropertiesFinder propertiesFinder = new PropertiesFinder();
            var nonExternMethods = inputAssemblies.GetAllDefinedMethods().Where(m => m.Body.Size > 0);
            var usedProperties   = propertiesFinder.FindPropertiesCalls(inputAssemblies).Except(nonExternMethods);

            if (Settings.StubGettersSettersWhitelist.Count > 0)
            {
                usedProperties = usedProperties.Where(p => Settings.StubGettersSettersWhitelist.Contains(BoogieMethod.From(p).Name));
            }

            var propertyFields = usedProperties.Select(propertyMethod => GetFieldDef(propertyMethod)).ToList().Distinct();

            foreach (var propertyDefinition in propertyFields)
            {
                streamWriter.WriteLine(propertyDefinition);
            }

            foreach (var property in usedProperties)
            {
                //streamWriter.WriteLine(GetFieldDef(property));
                var proc = property.Name.Value.StartsWith("get_") ? GetProcedureStub(property) : SetProcedureStub(property);
                streamWriter.WriteLine(proc);
            }
            return(usedProperties);
        }
コード例 #15
0
        // called from Traverser
        // set in Main
        public static void IMethodDefinitionTraverse(IMethodDefinition mD, IMetadataHost host, ISourceLocationProvider sourceLocationProvider)
        {
            // TODO: Hack to for treating a method as nondet
            var method     = mD.ResolvedMethod;
            var methodName = method.ContainingType.FullName() + "." + method.Name.Value;

            if (methodName.Equals("SVX.ContractBase.getNondet"))
            {
                InstructionTranslator.AddToExternalMethods(method);
                return;
            }
            // End Hack

            if (!mD.IsExternal)
            {
                try
                {
                    if (whitelistContains(mD.ContainingType.FullName()))
                    {
                        var        disassembler = new Disassembler(host, mD, sourceLocationProvider);
                        MethodBody mB           = disassembler.Execute();
                        transformBody(mB);

                        MethodTranslator methodTranslator = new MethodTranslator(mD, mB, Traverser.CHA);
                        // todo: improve this piece of code
                        StreamWriter streamWriter = Program.streamWriter;
                        streamWriter.WriteLine(methodTranslator.Translate());
                        Helpers.addTranslatedMethod(mD);
                    }
                }
                catch (InvalidOperationException ex)
                {
                    Console.WriteLine("WARNING: Exception thrown while translating method (omitting): " + BoogieMethod.From(mD).Name);
                    if (!Settings.SilentExceptionsForMethods)
                    {
                        throw ex;
                    }
                }
            }
        }
コード例 #16
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
            }
        }
コード例 #17
0
ファイル: TACWriter.cs プロジェクト: michael-emmi/TinyBCT
        // called from Traverser
        // set in Main
        public static void IMethodDefinitionTraverse(IMethodDefinition mD, IMetadataHost host, ISourceLocationProvider sourceLocationProvider)
        {
            if (!mD.IsExternal)
            {
                try
                {
                    var        disassembler = new Disassembler(host, mD, sourceLocationProvider);
                    MethodBody mB           = disassembler.Execute();
                    MethodTranslator.transformBody(mB);

                    TACWriter.AddMethod(mB);
                    TACWriter.Write();
                }
                catch (InvalidOperationException ex)
                {
                    Console.WriteLine("WARNING: Exception thrown while translating method (omitting): " + BoogieMethod.From(mD).Name);
                    if (!Settings.SilentExceptionsForMethods)
                    {
                        throw ex;
                    }
                }
            }
        }