예제 #1
0
        public InterProceduralReturnInfo DoInterProcWithCallee(InterProceduralCallInfo callInfo)
        {
            if ((!callInfo.Callee.IsExternal) && callInfo.Callee.Body.Operations.Any())
            {
                if (previousResult.ContainsKey(callInfo))
                {
                    var previousState = previousResult[callInfo];
                    if (callInfo.CallerState.LessEqual(previousState))
                    {
                        return(new InterProceduralReturnInfo(callInfo.CallerState));
                    }
                }

                this.previousResult[callInfo] = callInfo.CallerState;
                ControlFlowGraph calleeCFG = this.GetCFG(callInfo.Callee);


                var interProcresult = InterproceduralAnalysis(callInfo, calleeCFG);
                // For Debugging
//                if(interProcresult.State.LessEqual(previousState) && !interProcresult.State.Equals////(previousState))
//              { }
                return(interProcresult);
            }
            else
            {
            }
            return(new InterProceduralReturnInfo(callInfo.CallerState));
        }
예제 #2
0
        private DependencyPTGDomain BindCallerCallee(InterProceduralCallInfo callInfo, out VariableRangeDomain initializedRanges)
        {
            initializedRanges = new VariableRangeDomain();

            var calleeDepDomain = new DependencyPTGDomain();

            calleeDepDomain.Dependencies.IsTop = callInfo.CallerState.Dependencies.IsTop;
            // Bind parameters with arguments
            var body = MethodBodyProvider.Instance.GetBody(callInfo.Callee);

            for (int i = 0; i < body.Parameters.Count(); i++)
            {
                var arg = callInfo.CallArguments[i];

                var param = body.Parameters[i];

                arg   = AdaptIsReference(arg);
                param = AdaptIsReference(param);

                if (callInfo.CallerState.HasTraceables(arg))
                {
                    calleeDepDomain.AssignTraceables(param, callInfo.CallerState.GetTraceables(arg));
                }
                if (callInfo.CallerState.HasOutputTraceables(arg))
                {
                    calleeDepDomain.AddOutputTraceables(param, callInfo.CallerState.GetOutputTraceables(arg));
                }
                if (callInfo.CallerState.HasOutputControlTraceables(arg))
                {
                    calleeDepDomain.AddOutputControlTraceables(param, callInfo.CallerState.GetOutputControlTraceables(arg));
                }

                initializedRanges.AssignValue(param, callInfo.VariableRanges.GetValue(arg));

                // DIEGODIEGO: Do I need this?
                callInfo.ScopeData.PropagateCopy(arg, param);
            }
            calleeDepDomain.Dependencies.A1_Escaping = callInfo.CallerState.Dependencies.A1_Escaping;

            calleeDepDomain.Dependencies.A2_References = callInfo.CallerState.Dependencies.A2_References;

            calleeDepDomain.Dependencies.A3_Fields        = callInfo.CallerState.Dependencies.A3_Fields;
            calleeDepDomain.Dependencies.ControlVariables = callInfo.CallerState.Dependencies.ControlVariables;
            //calleeDepDomain.Dependencies.ControlTraceables = callInfo.CallerState.Dependencies.ControlTraceables;

            //calleeDepDomain.Dependencies.A1_Escaping.UnionWith(callInfo.CallerState.Dependencies.A1_Escaping);
            //calleeDepDomain.Dependencies.A3_Clousures.UnionWith(callInfo.CallerState.Dependencies.A3_Clousures);
            return(calleeDepDomain);
        }
예제 #3
0
        private DependencyPTGDomain BindCallerCallee(InterProceduralCallInfo callInfo)
        {
            var calleeDepDomain = new DependencyPTGDomain();

            calleeDepDomain.Dependencies.IsTop = callInfo.CallerState.Dependencies.IsTop;
            // Bind parameters with arguments
            for (int i = 0; i < callInfo.CallArguments.Count(); i++)
            {
                var arg   = callInfo.CallArguments[i];
                var param = callInfo.Callee.Body.Parameters[i];

                arg   = AdaptIsReference(arg);
                param = AdaptIsReference(param);

                if (callInfo.CallerState.HasTraceables(arg))
                {
                    calleeDepDomain.AssignTraceables(param, callInfo.CallerState.GetTraceables(arg));
                }
                if (callInfo.CallerState.HasOutputTraceables(arg))
                {
                    calleeDepDomain.AddOutputTraceables(param, callInfo.CallerState.GetOutputTraceables(arg));
                }
                if (callInfo.CallerState.HasOutputControlTraceables(arg))
                {
                    calleeDepDomain.AddOutputControlTraceables(param, callInfo.CallerState.GetOutputControlTraceables(arg));
                }
            }
            calleeDepDomain.Dependencies.A1_Escaping = callInfo.CallerState.Dependencies.A1_Escaping;

            calleeDepDomain.Dependencies.A2_References = callInfo.CallerState.Dependencies.A2_References;

            calleeDepDomain.Dependencies.A3_Fields        = callInfo.CallerState.Dependencies.A3_Fields;
            calleeDepDomain.Dependencies.ControlVariables = callInfo.CallerState.Dependencies.ControlVariables;
            //calleeDepDomain.Dependencies.A1_Escaping.UnionWith(callInfo.CallerState.Dependencies.A1_Escaping);
            //calleeDepDomain.Dependencies.A3_Clousures.UnionWith(callInfo.CallerState.Dependencies.A3_Clousures);
            return(calleeDepDomain);
        }
예제 #4
0
        private DependencyPTGDomain BindCalleeCaller(InterProceduralCallInfo callInfo, ControlFlowGraph calleeCFG,
                                                     IteratorDependencyAnalysis depAnalysis, RangeAnalysis rangeAnalysis)
        {
            var exitResult = depAnalysis.Result[calleeCFG.Exit.Id].Output;
            var exitRange  = rangeAnalysis.Result[calleeCFG.Exit.Id].Output;

            var body = MethodBodyProvider.Instance.GetBody(callInfo.Callee);

            for (int i = 0; i < body.Parameters.Count(); i++)
            {
                var arg   = callInfo.CallArguments[i];
                var param = body.Parameters[i];

                arg   = AdaptIsReference(arg);
                param = AdaptIsReference(param);

                if (exitResult.HasTraceables(param))
                {
                    callInfo.CallerState.AddTraceables(arg, exitResult.GetTraceables(param));
                }

                if (exitResult.HasOutputTraceables(param))
                {
                    callInfo.CallerState.AddOutputTraceables(arg, exitResult.GetOutputTraceables(param));
                }
                if (exitResult.HasOutputControlTraceables(param))
                {
                    callInfo.CallerState.AddOutputControlTraceables(arg, exitResult.GetOutputControlTraceables(param));
                }
            }

            foreach (var outputVar in exitResult.Dependencies.A4_Ouput.Keys)
            {
                //if (exitResult.HasOutputTraceables(outputVar))
                {
                    var newVar = new LocalVariable(callInfo.Callee.Name + "_" + outputVar.Name, callInfo.Callee)
                    {
                        Type = outputVar.Type
                    };
                    callInfo.CallerState.AddTraceables(newVar, exitResult.GetTraceables(outputVar));
                    callInfo.CallerState.AddOutputTraceables(newVar, exitResult.GetOutputTraceables(outputVar));
                    callInfo.CallerState.AddOutputControlTraceables(newVar, exitResult.GetOutputControlTraceables(outputVar));
                }
            }
            foreach (var outputVar in exitResult.Dependencies.A4_Ouput_Control.Keys.Except(exitResult.Dependencies.A4_Ouput.Keys))
            {
                //if (exitResult.HasOutputControlTraceables(outputVar))
                {
                    var newVar = new LocalVariable(callInfo.Callee.Name + "_" + outputVar.Name, callInfo.Callee)
                    {
                        Type = outputVar.Type
                    };
                    callInfo.CallerState.AddTraceables(newVar, exitResult.GetTraceables(outputVar));
                    callInfo.CallerState.AddOutputControlTraceables(newVar, exitResult.GetOutputControlTraceables(outputVar));
                }
            }


            callInfo.CallerState.Dependencies.A1_Escaping.UnionWith(exitResult.Dependencies.A1_Escaping);

            callInfo.CallerState.Dependencies.A2_References.UnionWith(exitResult.Dependencies.A2_References);
            callInfo.CallerState.Dependencies.A3_Fields.UnionWith(exitResult.Dependencies.A3_Fields);

            //callInfo.CallerState.Dependencies.ControlTraceables.UnionWith(exitResult.Dependencies.ControlTraceables);


            callInfo.CallerState.Dependencies.IsTop |= exitResult.Dependencies.IsTop;

            if (callInfo.CallLHS != null)
            {
                // Need to bind the return value
                if (exitResult.Dependencies.A2_Variables.ContainsKey(depAnalysis.ReturnVariable) &&
                    exitResult.HasTraceables(depAnalysis.ReturnVariable))
                {
                    callInfo.CallerState.AssignTraceables(callInfo.CallLHS, exitResult.GetTraceables(depAnalysis.ReturnVariable));
                }
                if (exitResult.Dependencies.A4_Ouput.ContainsKey(depAnalysis.ReturnVariable) &&
                    exitResult.HasOutputTraceables(depAnalysis.ReturnVariable))
                {
                    callInfo.CallerState.AddOutputTraceables(callInfo.CallLHS, exitResult.GetOutputTraceables(depAnalysis.ReturnVariable));
                }
                if (exitResult.Dependencies.A4_Ouput_Control.ContainsKey(depAnalysis.ReturnVariable) &&
                    exitResult.HasOutputControlTraceables(depAnalysis.ReturnVariable))
                {
                    callInfo.CallerState.AddOutputControlTraceables(callInfo.CallLHS, exitResult.GetOutputControlTraceables(depAnalysis.ReturnVariable));
                }

                // DIEGODIEGO: Need to propagate range of return value
                callInfo.VariableRanges.AssignValue(callInfo.CallLHS, exitRange.GetValue(rangeAnalysis.ReturnVariable));
            }

            return(callInfo.CallerState);
        }
예제 #5
0
        /// This does the interprocedural analysis.
        /// It (currently) does NOT support recursive method invocations
        /// </summary>
        /// <param name="instruction"></param>
        /// <param name="resolvedCallee"></param>
        /// <param name="calleeCFG"></param>
        private InterProceduralReturnInfo InterproceduralAnalysis(InterProceduralCallInfo callInfo, ControlFlowGraph calleeCFG)
        {
            if (stackDepth > InterproceduralManager.MaxStackDepth)
            {
                callInfo.CallerState.Dependencies.IsTop = true;
                AnalysisStats.AddAnalysisReason(new AnalysisReason(callInfo.Caller, callInfo.Instruction, String.Format(CultureInfo.InvariantCulture, "Reach maximum call depth {0}", callInfo.Callee.Name)));
                return(new InterProceduralReturnInfo(callInfo.CallerState));
            }

            stackDepth++;
            // I currently do not support recursive calls
            // Will add support for this in the near future
            if (callStack.Contains(callInfo.Callee))
            {
                callInfo.CallerState.Dependencies.IsTop = true;
                AnalysisStats.AddAnalysisReason(new AnalysisReason(callInfo.Caller, callInfo.Instruction, String.Format(CultureInfo.InvariantCulture, "Recursive call to {0}", callInfo.Callee.Name)));
                return(new InterProceduralReturnInfo(callInfo.CallerState));
            }

            this.callStack.Push(callInfo.Callee);
            //Console.WriteLine("Analyzing Method {0} Stack: {1}", new string(' ',stackDepth*2) + callInfo.Callee.ToString(), stackDepth);
            // 1) Bind PTG and create a Poinst-to Analysis for the  callee. In pta.Result[node.Exit] is the PTG at exit of the callee
            var calleePTG = PTABindCallerCallee(callInfo.CallerPTG, callInfo.CallArguments, callInfo.Callee);
            SimplePointsToAnalysis calleePTA = new SimplePointsToAnalysis(calleeCFG, callInfo.Callee, calleePTG);

            IDictionary <IVariable, IExpression> equalities = new Dictionary <IVariable, IExpression>();

            calleeCFG.PropagateExpressions(equalities);

            // 2) Bind Parameters of the dependency analysis
            VariableRangeDomain boundVariablesRanges;
            var calleeDomain   = BindCallerCallee(callInfo, out boundVariablesRanges);
            var rangesAnalysis = new RangeAnalysis(calleeCFG, callInfo.Callee, boundVariablesRanges);

            // 4) Now we perform the analyses
            rangesAnalysis.Analyze();

            calleeDomain.PTG = calleePTG;
            var dependencyAnalysis = new IteratorDependencyAnalysis(processToAnalyze, callInfo.Callee, calleeCFG, calleePTA, callInfo.ProtectedNodes, equalities, this, rangesAnalysis, calleeDomain, callInfo.ScopeData);

            // If we already did the dataflow analysis for this method we recover the dataflow state
            // This should be adapted (or removed) if we want the analysis to be context sensitive

            //if (dataflowCache.ContainsKey(callInfo.Callee))
            //{
            //    var previosResult = dataflowCache[callInfo.Callee];
            //    //DataFlowAnalysisResult<DependencyPTGDomain>[] resultsCopy = new DataFlowAnalysisResult<DependencyPTGDomain>[previosResult.Length];
            //    //for(int i=0; i< previosResult.Length; i++)
            //    //{
            //    //    resultsCopy[i] = new DataFlowAnalysisResult<DependencyPTGDomain>();
            //    //    resultsCopy[i].Input = previosResult[i].Input!=null? previosResult[i].Input.Clone(): null;
            //    //    resultsCopy[i].Output = previosResult[i].Output!=null? previosResult[i].Output.Clone(): null;
            //    //}
            //    //dependencyAnalysis.SetPreviousResult(resultsCopy);

            //    dependencyAnalysis.SetPreviousResult(previosResult);
            //}

            dependencyAnalysis.Analyze();


            this.dataflowCache[callInfo.Callee] = dependencyAnalysis.Result;

            stackDepth--;
            this.callStack.Pop();

            // 3) Bind callee with caller
            // Should I need the PTG of caller and callee?
            //var exitCalleePTG = calleePTA.Result[calleeCFG.Exit.Id].Output;
            var exitCalleePTG = dependencyAnalysis.Result[calleeCFG.Exit.Id].Output.PTG;


            var exitResult = BindCalleeCaller(callInfo, calleeCFG, dependencyAnalysis, rangesAnalysis);

            // Recover the frame of the original Ptg and bind ptg results
            //PointsToGraph bindPtg = PTABindCaleeCalleer(callInfo.CallLHS, calleeCFG, calleePTA);
            var bindPtg = PTABindCaleeCalleer(callInfo.CallLHS, calleeCFG, exitCalleePTG, calleePTA.ReturnVariable);

            exitResult.PTG = bindPtg;

            return(new InterProceduralReturnInfo(exitResult)
            {
                InputColumns = dependencyAnalysis.InputColumns,
                OutputColumns = dependencyAnalysis.OutputColumns
            });
            //return new InterProceduralReturnInfo(exitResult, bindPtg);
        }