예제 #1
0
        /// <summary>
        /// Execute is the pass's prime mover; all unit-centric processing occurs here. Note that
        /// Execute might be thought of as a "callback": as the C2 host compiles each FunctionUnit,
        /// passing it from pass to pass, the plug-in Execute method is called to do its work.
        /// </summary>
        ///
        /// <param name="moduleUnit">The moduleUnit to process.</param>
        /// <returns>True if successful; false otherwise.</returns>
        protected override bool Execute(Phx.ModuleUnit moduleUnit)
        {
            try
            {
                this.ExecuteHelper(moduleUnit);
            }
            catch (System.Exception ex)
            {
                Console.Out.WriteLine("PHOENIX: Exception occurred:");
                Console.Out.WriteLine(ex.Message);
                Console.Out.WriteLine("PHOENIX: Stack trace:");
                Console.Out.WriteLine(ex.StackTrace);
                Console.Out.WriteLine("PHOENIX: Exiting GameTime...");
                Environment.Exit(1);
                return(false);
            }

            return(true);
        }
예제 #2
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);
        }