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)); }
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); }
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); }
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); }
/// 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); }