Ejemplo n.º 1
0
 /// <summary>
 /// Initialize the dependent architectures and runtimes.
 /// </summary>
 private static void InitializeTargets()
 {
     Phx.Targets.Architectures.Architecture msilArch         = Phx.Targets.Architectures.Msil.Architecture.New();
     Phx.Targets.Runtimes.Runtime           win32MSILRuntime = Phx.Targets.Runtimes.Vccrt.Win.Msil.Runtime.New(msilArch);
     Phx.GlobalData.RegisterTargetArchitecture(msilArch);
     Phx.GlobalData.RegisterTargetRuntime(win32MSILRuntime);
 }
Ejemplo n.º 2
0
        /// <summary>
        /// Instrument the assembly.
        /// </summary>
        /// <returns>Termination mode of the processing.</returns>
        public static Phx.Term.Mode Process()
        {
            string currentAssembly = Application.Input.GetValue(null);

            // Create the log file with details about the basic blocks
            using (LogWriter log = new LogWriter(Path.ChangeExtension(currentAssembly, "Coverage.xml")))
            {
                log.Start();

                Phx.Output.WriteLine("Instrumenting code coverage for " + currentAssembly + " ...");
                log.StartAssembly(currentAssembly);

                // Get the architecture and runtime from the existing assembly
                Phx.PEModuleUnit oldModule = Phx.PEModuleUnit.Open(currentAssembly);
                Phx.Targets.Architectures.Architecture architecture = oldModule.Architecture;
                Phx.Targets.Runtimes.Runtime           runtime      = oldModule.Runtime;
#if VS2010
                string clrVersion = oldModule.ClrVersionString;
#endif
                oldModule.Close();
                oldModule.Delete();

                // Create an empty program to contain the instrumented code
                Phx.Lifetime    lifetime = Phx.Lifetime.New(Phx.LifetimeKind.Global, null);
                Phx.ProgramUnit program  = Phx.ProgramUnit.New(
                    lifetime,
                    null,
                    Phx.GlobalData.TypeTable,
                    architecture,
                    runtime);
                Phx.PEModuleUnit module = Phx.PEModuleUnit.New(
                    lifetime,
                    Phx.Name.New(lifetime, Path.GetFullPath(currentAssembly)),
                    program,
                    Phx.GlobalData.TypeTable,
                    architecture,
                    runtime);

                // Set to metadata version 2 if none was copied
#if VS2010
                if (clrVersion == null)
                {
                    clrVersion = PreferredClrVersion;
                    module.ClrVersionString = clrVersion;
                }
#endif

                // Dev10 Phoenix seems to require this fix
#if VS2010
                module.RaiseMsilOnly = true;
#endif

                // Create the phase list:
                // 1. For each function
                //    a. Raise the binary executable code to LIR
                //    b. Instrument function with code coverage calls
                //    c. Encode the instrumented code
                // 2. Emit the instrumented program as a binary
                Phx.Phases.PhaseConfiguration phases = Phx.Phases.PhaseConfiguration.New(lifetime, "CodeCoverage Phases");
                phases.PhaseList.AppendPhase(Phx.PE.ReaderPhase.New(phases));
                Phx.Phases.PhaseList functionPhases = Phx.PE.UnitListPhaseList.New(phases, Phx.PE.UnitListWalkOrder.PrePass);
                functionPhases.AppendPhase(Phx.PE.RaiseIRPhase.New(phases, Phx.FunctionUnit.LowLevelIRBeforeLayoutFunctionUnitState));
                functionPhases.AppendPhase(InstrumentPhase.New(phases, log));
                functionPhases.AppendPhase(EncodePhase.New(phases));
                functionPhases.AppendPhase(Phx.PE.DiscardIRPhase.New(phases));
                phases.PhaseList.AppendPhase(functionPhases);
                phases.PhaseList.AppendPhase(EmitPhase.New(phases));
                Phx.GlobalData.BuildPlugInPhases(phases);

                // Run Phoenix using our phases
                phases.PhaseList.DoPhaseList(module);

                // Close the log file
                log.EndAssembly();
                log.Close();
            }

            return(Phx.Term.Mode.Normal);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Private helper workhorse function for <see cref="Execute"/>.
        /// </summary>
        ///
        /// <param name="moduleUnit">The moduleUnit to process.</param>
        /// <returns>True if successful; false otherwise.</returns>
        private bool ExecuteHelper(Phx.ModuleUnit moduleUnit)
        {
            Console.Out.WriteLine();

            Phx.Graphs.CallGraph callGraph = moduleUnit.CallGraph;
            if (callGraph == null)
            {
                Console.Out.WriteLine("PHOENIX: Call graph is null.");
                Console.Out.WriteLine("Exiting GameTime.");
                Environment.Exit(1);
                return(false);
            }

            /* Load GameTime configuration. */
            string configFile = Console.ReadLine();

            Console.Out.WriteLine("PHOENIX: Configuring this GameTime session with " +
                                  configFile + "...");
            Utilities.Configuration config = Utilities.Configuration.ReadConfigFile(configFile);
            Console.Out.WriteLine("PHOENIX: Successfully configured this session.");

            /* Load the project configuration. */
            string projectConfigFile = Console.ReadLine();

            Console.Out.WriteLine("PHOENIX: Loading project configuration from " +
                                  projectConfigFile + "...");
            ProjectConfiguration projectConfig =
                ProjectConfiguration.ReadProjectConfigFile(projectConfigFile, config);

            Console.Out.WriteLine("PHOENIX: Successfully loaded the project for this session.");

            /* Determine the current GameTime operation mode. */
            string currentMode = Console.ReadLine();

            mode = (currentMode.Equals(config.TEMP_PHX_CREATE_DAG)) ?
                   MODES.CREATE_DAG : MODES.FIND_CONDITIONS;
            Console.Out.WriteLine("PHOENIX: GameTime operation mode is: " +
                                  ((mode == MODES.CREATE_DAG) ? "Create DAG." : "Find path conditions."));

            /* Find the function to analyze. */
            string funcToProcess = projectConfig.func;

            Console.Out.WriteLine("PHOENIX: Preprocessing " + funcToProcess + "...");
            Console.Out.WriteLine();

            Console.Out.WriteLine("PHOENIX: Finding the corresponding function unit...");

            /* Find the function unit corresponding to the function to be analyzed. */
            FunctionUnit functionUnitToProcess = null;

            /* Traverse the graph in post-order (top-down order). */
            Phx.Graphs.NodeFlowOrder nodeOrder = Phx.Graphs.NodeFlowOrder.New(callGraph.Lifetime);
            nodeOrder.Build(callGraph, Phx.Graphs.Order.PostOrder);
            Phx.Targets.Runtimes.Runtime runtime = moduleUnit.Runtime;
            uint functionCount = 0;

            for (uint i = 1; i <= nodeOrder.NodeCount; ++i)
            {
                Phx.Graphs.CallNode node = nodeOrder.Node(i).AsCallNode;
                if ((node == callGraph.UnknownCallerNode) ||
                    (node == callGraph.UnknownCalleeNode))
                {
                    continue;
                }
                if (node.FunctionSymbol != null)
                {
                    /* Is this LTCG mode? */
                    bool isLTCG = false;
                    try
                    {
                        IDictionary env = Environment.GetEnvironmentVariables();
                        if (env.Contains("LINK_TIME_CODE_GENERATION"))
                        {
                            isLTCG = true;
                        }
                    }
                    catch (ArgumentNullException) { }

                    /* Only perform the check when the LTCG mode is off. */
                    if (isLTCG || moduleUnit.IsPEModuleUnit)
                    {
                        moduleUnit = node.FunctionSymbol.CompilationUnitParentSymbol.Unit.AsModuleUnit;
                    }

                    /* Create the corresponding function unit. */
                    Phx.Lifetime     lifetime     = Phx.Lifetime.New(Phx.LifetimeKind.Function, null);
                    Phx.FunctionUnit functionUnit = Phx.FunctionUnit.New(lifetime,
                                                                         node.FunctionSymbol, Phx.CodeGenerationMode.Native,
                                                                         moduleUnit.TypeTable, runtime.Architecture, runtime,
                                                                         moduleUnit, functionCount++);

                    /* Attach debugging info. */
                    Phx.Debug.Info.New(functionUnit.Lifetime, functionUnit);

                    node.FunctionSymbol.FunctionUnit = functionUnit;
                    this.PhaseConfiguration.PhaseList.DoPhaseList(functionUnit);
                    functionUnit.Context.PopUnit();

                    string funcName = FunctionUnitHelper.GetFunctionName(functionUnit);
                    if (funcName == funcToProcess)
                    {
                        functionUnitToProcess = functionUnit;
                        break;
                    }
                }
            }

            if (functionUnitToProcess == null)
            {
                Console.Out.WriteLine("PHOENIX: Cannot find function named " + funcToProcess + ".");
                Console.Out.WriteLine("PHOENIX: Exiting GameTime...");
                Environment.Exit(1);
                return(false);
            }
            else
            {
                Console.Out.WriteLine("PHOENIX: Function unit found.");
            }

            Console.Out.WriteLine("PHOENIX: Preprocessing the function unit...");
            FunctionUnitHelper.Preprocess(functionUnitToProcess);
            Console.Out.WriteLine("PHOENIX: Function unit preprocessing complete.");
            Console.Out.WriteLine();

            Console.Out.WriteLine("PHOENIX: Building the flow graph...");
            functionUnitToProcess.BuildFlowGraphWithoutEH();
            Phx.Graphs.FlowGraph graph = functionUnitToProcess.FlowGraph;
            Console.Out.WriteLine("PHOENIX: Flow graph built.");

            Console.Out.WriteLine("PHOENIX: Snipping the relevant portion of the flow graph...");

            uint sourceBlockId = 1;
            uint sinkBlockId   = graph.NodeCount;

            if (projectConfig.startLabel != "")
            {
                Phx.Graphs.BasicBlock sourceBlock =
                    FunctionUnitHelper.SplitAtUserLabel(functionUnitToProcess,
                                                        projectConfig.startLabel);
                sourceBlockId = sourceBlock.Id;
            }
            if (projectConfig.endLabel != "")
            {
                Phx.Graphs.BasicBlock sinkBlock =
                    FunctionUnitHelper.SplitAtUserLabel(functionUnitToProcess,
                                                        projectConfig.endLabel);

                /* Correct the sink block: we want the block just before the block
                 * we receive from SplitAtUserLabel. */
                Phx.Graphs.FlowEdge edgeToSink = sinkBlock.PredecessorEdgeList;
                sinkBlock   = edgeToSink.PredecessorNode;
                sinkBlockId = sinkBlock.Id;
            }

            Console.Out.WriteLine("PHOENIX: Relevant portion snipped.");
            Console.Out.WriteLine();

            Console.Out.WriteLine("PHOENIX: Starting analysis...");

            switch (mode)
            {
            case MODES.CREATE_DAG:
                FunctionUnitHelper.DumpCfgToFile(functionUnitToProcess,
                                                 sourceBlockId, sinkBlockId, config, projectConfig);
                break;

            case MODES.FIND_CONDITIONS:
                FunctionUnitHelper.FindPathConditions(functionUnitToProcess,
                                                      config, projectConfig);
                break;
            }

            Console.Out.WriteLine("PHOENIX: Analysis successful.");
            Console.Out.WriteLine();

            Environment.Exit(0);
            return(true);
        }