public DependencyPTGDomain(DependencyDomain dependencies, SimplePointsToGraph ptg) { Dependencies = dependencies; PTG = ptg; IteratorState = RangeDomain.BOTTOM; // new RangeDomain(-1); BlockState = RangeDomain.BOTTOM; }
public DependencyPTGDomain(DependencyDomain dependencies, SimplePointsToGraph ptg, RangeDomain itState, RangeDomain blockState) { Dependencies = dependencies; PTG = ptg; IteratorState = itState; BlockState = blockState; }
public DependencyPTGDomain() { Dependencies = new DependencyDomain(); PTG = new SimplePointsToGraph(); IteratorState = RangeDomain.BOTTOM; // new RangeDomain(-1); BlockState = RangeDomain.BOTTOM; }
public DependencyPTGDomain AnalyzeMoveNextMethod() { // 1) Analyze the entry method that creates, populates and return the clousure var cfgEntry = entryMethod.DoAnalysisPhases(host); var pointsToEntry = new IteratorPointsToAnalysis(cfgEntry, this.entryMethod); // , this.specialFields); var entryResult = pointsToEntry.Analyze(); var ptgOfEntry = entryResult[cfgEntry.Exit.Id].Output; // 2) Call the GetEnumerator that may create a new clousure and polulate it var myGetEnumResult = new LocalVariable("$_temp_it") { Type = getEnumMethod.ReturnType }; ptgOfEntry.Add(myGetEnumResult); var ptgAfterEnum = this.interprocManager.PTAInterProcAnalysis(ptgOfEntry, new List <IVariable> { pointsToEntry.ReturnVariable }, myGetEnumResult, this.getEnumMethod); // These are the nodes that we want to protect/analyze var protectedNodes = ptgOfEntry.Nodes.OfType <ParameterNode>() .Where(n => IsScopeType(n.Type)).Select(n => new ProtectedRowNode(n, ProtectedRowNode.GetKind(n.Type))); // I no longer need this. //var specialFields = cfgEntry.ForwardOrder[1].Instructions.OfType<StoreInstruction>() // .Where(st => st.Result is InstanceFieldAccess).Select(st => new KeyValuePair<string,IVariable>((st.Result as InstanceFieldAccess).FieldName,st.Operand) ); //this.specialFields = specialFields.ToDictionary(item => item.Key, item => item.Value); // 3) I bing the current PTG with the parameters of MoveNext method on the clousure // Well... Inlining is broken we we added the Exceptional control graph. Let's avoid it //var cfg = this.moveNextMethod.DoAnalysisPhases(host, this.GetMethodsToInline()); var cfg = this.interprocManager.GetCFG(this.moveNextMethod); PropagateExpressions(cfg, this.equalities); // In general, the variable to bind is going to be pointsToEntry.ReturnVariable which is aliased with "$_temp_it" (myGetEnumResult) SimplePointsToGraph calleePTG = InterproceduralManager.PTABindCallerCallee(ptgAfterEnum, new List <IVariable> { myGetEnumResult }, this.moveNextMethod); this.pointsToAnalyzer = new IteratorPointsToAnalysis(cfg, this.moveNextMethod, calleePTG); //this.pta= this.interprocManager.PTABindAndRunInterProcAnalysis(ptgAfterEnum, new List<IVariable> { myGetEnumResult }, this.moveNextMethod, cfg); //var pointsTo = new IteratorPointsToAnalysis(cfg, this.moveNextMethod, this.specialFields); //this.ptAnalysisResult = pointsTo.Analyze(); // var pointsTo = new IteratorPointsToAnalysis(cfg, this.moveNextMethod, this.specialFields, ptgOfEntry); // Now I analyze the Movenext method with the proper initialization var result = this.AnalyzeScopeMethod(cfg, pointsToAnalyzer, protectedNodes); return(result); }
public SimplePointsToAnalysis PTABindAndRunInterProcAnalysis(SimplePointsToGraph ptg, IList <IVariable> arguments, IMethodDefinition resolvedCallee, ControlFlowGraph calleeCFG) { var bindPtg = PTABindCallerCallee(ptg, arguments, resolvedCallee); // Compute PT analysis for callee var pta = new SimplePointsToAnalysis(calleeCFG, resolvedCallee, bindPtg); pta.Analyze(); return(pta); }
/// 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> public SimplePointsToGraph PTAInterProcAnalysis(SimplePointsToGraph ptg, IList <IVariable> arguments, IVariable result, IMethodDefinition resolvedCallee) { if (resolvedCallee.ResolvedMethod.Body.Operations.Any()) { ControlFlowGraph calleeCFG = this.GetCFG(resolvedCallee); //DGMLSerializer.Serialize(calleeCFG); stackDepth++; SimplePointsToAnalysis pta = this.PTABindAndRunInterProcAnalysis(ptg, arguments, resolvedCallee, calleeCFG); stackDepth--; return(PTABindCaleeCalleer(result, calleeCFG, pta)); } return(ptg); }
public static SimplePointsToGraph PTABindCallerCallee(SimplePointsToGraph ptg, IList <IVariable> arguments, MethodDefinition resolvedCallee) { var bindPtg = ptg.Clone(); var argParamMap = new Dictionary <IVariable, IVariable>(); // Bind parameters with arguments in PTA for (int i = 0; i < arguments.Count(); i++) { argParamMap[arguments[i]] = resolvedCallee.Body.Parameters[i]; } bindPtg.NewFrame(argParamMap); bindPtg.PointsTo(IteratorPointsToAnalysis.GlobalVariable, SimplePointsToGraph.GlobalNode); return(bindPtg); }
public DependencyPTGDomain(DependencyDomain dependencies, SimplePointsToGraph ptg) { Dependencies = dependencies; PTG = ptg; }
public DependencyPTGDomain() { Dependencies = new DependencyDomain(); PTG = new SimplePointsToGraph(); }
public Tuple <IEnumerable <IMethodDefinition>, IEnumerable <IMethodReference> > ComputePotentialCallees(MethodCallInstruction instruction, SimplePointsToGraph ptg) { var resolvedCallees = new HashSet <IMethodDefinition>(); var unresolvedCallees = new HashSet <IMethodReference>(); var potentalDelegateCall = instruction.Method; // If it is a delegate if (potentalDelegateCall.Name.Value == "Invoke") { var classDef = (potentalDelegateCall.ContainingType.ResolvedType) as INamedTypeDefinition; if (classDef != null && classDef.IsDelegate) { var delegateVar = instruction.Arguments[0]; return(ComputeDelegate(delegateVar, ptg)); //var potentialDelegates = ptg.GetTargets(delegateVar); //var resolvedInvocations = potentialDelegates.OfType<DelegateNode>() // .Select(d => this.host.FindMethodImplementation(d.Instance.Type as BasicType, d.Method) as IMethodReference); //resolvedCallees.UnionWith(resolvedInvocations.OfType<MethodDefinition>()); //unresolvedCallees.UnionWith(resolvedInvocations.Where(c => !resolvedCallees.Contains(c))); } } else { if (!instruction.Method.IsStatic && instruction.Method.Name.Value != ".ctor") { var receiver = instruction.Arguments[0]; var types = ptg.GetTargets(receiver, false).Where(n => n.Kind != SimplePTGNodeKind.Null && n.Type != null).Select(n => n.Type); var candidateCalless = types.Select(t => t.FindMethodImplementation(instruction.Method)); var resolvedInvocations = candidateCalless.Select(c => c.ResolvedMethod as IMethodReference); resolvedCallees.UnionWith(resolvedInvocations.OfType <IMethodDefinition>()); unresolvedCallees.UnionWith(candidateCalless.Where(c => !resolvedInvocations.Contains(c) && (c.Name.Value != "Dispose" && c.ContainingType.ContainingAssembly() == "mscorlib"))); //unresolvedCallees.UnionWith(resolvedInvocations.Where(c => !(c is MethodDefinition))); } else { var candidateCalee = instruction.Method.ContainingType.FindMethodImplementation(instruction.Method); var resolvedCalle = candidateCalee.ResolvedMethod; if (resolvedCalle != null) { resolvedCallees.Add(resolvedCalle); } } } return(new Tuple <IEnumerable <IMethodDefinition>, IEnumerable <IMethodReference> >(resolvedCallees, unresolvedCallees)); }
public Tuple <IEnumerable <IMethodDefinition>, IEnumerable <IMethodReference> > ComputeDelegate(IVariable delegateArgument, SimplePointsToGraph ptg) { var resolvedCallees = new HashSet <IMethodDefinition>(); var unresolvedCallees = new HashSet <IMethodReference>(); var potentialDelegates = ptg.GetTargets(delegateArgument); var resolvedInvocations = potentialDelegates.OfType <DelegateNode>() .Select(d => d.Instance.Type.FindMethodImplementation(d.Method)); resolvedCallees.UnionWith(resolvedInvocations.OfType <IMethodDefinition>()); unresolvedCallees.UnionWith(resolvedInvocations.Where(c => !resolvedCallees.Contains(c))); return(new Tuple <IEnumerable <IMethodDefinition>, IEnumerable <IMethodReference> >(resolvedCallees, unresolvedCallees)); }
private SimplePointsToGraph PTABindCaleeCalleer(IVariable result, ControlFlowGraph calleeCFG, SimplePointsToGraph calleePTG, IVariable rv) { var exitPTG = calleePTG; if (result != null) { exitPTG.RestoreFrame(rv, result); } else { exitPTG.RestoreFrame(); } return(exitPTG); }
public static string Serialize(SimplePointsToGraph ptg) { using (var stringWriter = new StringWriter()) using (var xmlWriter = new XmlTextWriter(stringWriter)) { xmlWriter.Formatting = Formatting.Indented; xmlWriter.WriteStartElement("DirectedGraph"); xmlWriter.WriteAttributeString("xmlns", "http://schemas.microsoft.com/vs/2009/dgml"); xmlWriter.WriteStartElement("Nodes"); foreach (var variable in ptg.Roots) { var label = variable.Name; xmlWriter.WriteStartElement("Node"); xmlWriter.WriteAttributeString("Id", label); xmlWriter.WriteAttributeString("Label", label); xmlWriter.WriteAttributeString("Shape", "None"); xmlWriter.WriteEndElement(); } foreach (var node in ptg.Nodes) { var nodeId = Convert.ToString(node.Id); var label = nodeId + ":" + Serialize(node); xmlWriter.WriteStartElement("Node"); xmlWriter.WriteAttributeString("Id", nodeId); xmlWriter.WriteAttributeString("Label", label); if (node.Kind == SimplePTGNodeKind.Null) { xmlWriter.WriteAttributeString("Background", "Black"); } else if (node.Kind == SimplePTGNodeKind.Global) { xmlWriter.WriteAttributeString("Background", "Blue"); } else if (node.Kind == SimplePTGNodeKind.Delegate) { xmlWriter.WriteAttributeString("Background", "Cyan"); } else if (node.Kind == SimplePTGNodeKind.Parameter) { xmlWriter.WriteAttributeString("Background", "Red"); xmlWriter.WriteAttributeString("StrokeDashArray", "6,6"); } else if (node.Kind == SimplePTGNodeKind.Unknown) { xmlWriter.WriteAttributeString("Background", "Yellow"); xmlWriter.WriteAttributeString("StrokeDashArray", "6,6"); } xmlWriter.WriteEndElement(); } xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("Links"); foreach (var variable in ptg.Roots) { var sourceId = variable.Name; foreach (var target in ptg.GetTargets(variable)) { var targetId = Convert.ToString(target.Id); xmlWriter.WriteStartElement("Link"); xmlWriter.WriteAttributeString("Source", sourceId); xmlWriter.WriteAttributeString("Target", targetId); xmlWriter.WriteEndElement(); } } foreach (var node in ptg.Nodes) { var sourceId = Convert.ToString(node.Id); foreach (var targetMap in ptg.GetTargets(node)) { foreach (var target in targetMap.Value) { var targetId = Convert.ToString(target.Id); var label = targetMap.Key.Name; xmlWriter.WriteStartElement("Link"); xmlWriter.WriteAttributeString("Source", sourceId); xmlWriter.WriteAttributeString("Target", targetId); xmlWriter.WriteAttributeString("Label", label.Value); xmlWriter.WriteEndElement(); } } } xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("Styles"); xmlWriter.WriteStartElement("Style"); xmlWriter.WriteAttributeString("TargetType", "Node"); xmlWriter.WriteStartElement("Setter"); xmlWriter.WriteAttributeString("Property", "FontFamily"); xmlWriter.WriteAttributeString("Value", "Consolas"); xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("Setter"); xmlWriter.WriteAttributeString("Property", "NodeRadius"); xmlWriter.WriteAttributeString("Value", "5"); xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("Setter"); xmlWriter.WriteAttributeString("Property", "MinWidth"); xmlWriter.WriteAttributeString("Value", "0"); xmlWriter.WriteEndElement(); xmlWriter.WriteEndElement(); xmlWriter.WriteEndElement(); xmlWriter.WriteEndElement(); xmlWriter.Flush(); return(stringWriter.ToString()); } }
public Tuple <DependencyPTGDomain, TimeSpan> AnalyzeMoveNextMethod() { AnalysisStats.extraAnalysisOverHead = new Stopwatch(); var sw = new Stopwatch(); sw.Start(); // 0) Analyze static fields. // DIEGODIEGO: Should I also Include the points-to graph??? var staticConstructor = processToAnalyze.ProcessorClass.Methods.SingleOrDefault(m => m.Name.Value == ".cctor"); if (staticConstructor != null) { var cfgcCtor = staticConstructor.DoAnalysisPhases(host, sourceLocationProvider); var rangeAnalysisCctor = new RangeAnalysis(cfgcCtor, staticConstructor); rangeAnalysisCctor.Analyze(); } // The following steps generates a PTG for the MoveNext method that takes into account the context of invocation // This is the Producer entry method and the call to GetEnumerator which then is used in the Movenext method // 1) Analyze the entry method that creates, populates and return the clousure var cfgEntry = processToAnalyze.EntryMethod.DoAnalysisPhases(host, sourceLocationProvider); var pointsToEntry = new SimplePointsToAnalysis(cfgEntry, processToAnalyze.EntryMethod); var entryResult = pointsToEntry.Analyze(); var ptgOfEntry = entryResult[cfgEntry.Exit.Id].Output; // 2) Call the GetEnumerator that may create a new clousure and polulate it var myGetEnumResult = new LocalVariable("$_temp_it", processToAnalyze.EntryMethod) { Type = processToAnalyze.GetIteratorMethod.Type }; ptgOfEntry.Add(myGetEnumResult); var ptgAfterEnum = this.interprocManager.PTAInterProcAnalysis(ptgOfEntry, new List <IVariable> { pointsToEntry.ReturnVariable }, myGetEnumResult, processToAnalyze.GetIteratorMethod); // These are the nodes that we want to protect/analyze var protectedNodes = ptgOfEntry.Nodes.OfType <ParameterNode>() .Where(n => IsScopeType(n.Type)).Select(n => new ProtectedRowNode(n, ProtectedRowNode.GetKind(n.Type))); // Create tables representing the input and output tables this.inputTable = new TraceableTable(protectedNodes.Single(pn => pn.RowKind == ProtectedRowKind.Input)); this.outputTable = new TraceableTable(protectedNodes.Single(pn => pn.RowKind == ProtectedRowKind.Output)); // 3) I bing the current PTG with the parameters of MoveNext method on the clousure // Well... Inlining is broken we we added the Exceptional control graph. Let's avoid it //var cfg = this.moveNextMethod.DoAnalysisPhases(host, this.GetMethodsToInline()); var cfg = this.interprocManager.GetCFG(processToAnalyze.MoveNextMethod); cfg.PropagateExpressions(this.equalities); // In general, the variable to bind is going to be pointsToEntry.ReturnVariable which is aliased with "$_temp_it" (myGetEnumResult) SimplePointsToGraph calleePTG = InterproceduralManager.PTABindCallerCallee(ptgAfterEnum, new List <IVariable> { myGetEnumResult }, processToAnalyze.MoveNextMethod); this.pointsToAnalyzer = new SimplePointsToAnalysis(cfg, processToAnalyze.MoveNextMethod, calleePTG); // Now I analyze the Movenext method with the proper initialization var result = this.AnalyzeScopeMethod(cfg, pointsToAnalyzer, protectedNodes); sw.Stop(); //return Tuple.Create(result, sw.Elapsed - AnalysisStats.extraAnalysisOverHead.Elapsed); return(Tuple.Create(result, sw.Elapsed)); }
internal PTAVisitor(SimplePointsToGraph ptg, IteratorPointsToAnalysis ptAnalysis) { this.State = ptg; this.ptAnalysis = ptAnalysis; this.analyzeNextDelegateCtor = false; }