protected DataFlowAnalysisBase(ICFG cfg) { this.CFG = cfg; this.pending = new PriorityQueue <APC> (WorkingListComparer); this.JoinState = new Dictionary <APC, AState> (this); this.widen_strategy = null; }
public ParametersFixMethodCallReturnValue(ProofObligation obl, APC pc, Func <APC> pcWithSourceContext, Variable dest, ArgList args, BoxedExpression condition, List <BoxedExpression> premises, Method method, IDecodeMethods <Method> mdDecoder, ICFG cfg, Func <APC, BoxedExpression, bool, BoxedExpression> ReadAt, Func <APC, Variable, FList <PathElement> > AccessPath, Func <FList <PathElement>, bool> IsRootedInParameter, Func <Variable, FList <PathElement>, BoxedExpression> MakeMethodCall, Func <Variable, BoxedExpression> MakeEqualZero ) { Contract.Requires(mdDecoder != null); this.obl = obl; this.pc = pc; this.pcWithSourceContext = pcWithSourceContext; this.dest = dest; this.args = args; this.condition = condition; this.premises = premises; this.mdDecoder = mdDecoder; this.cfg = cfg; this.method = method; this.ReadAt = ReadAt; this.AccessPath = AccessPath; this.IsRootedInParameter = IsRootedInParameter; this.MakeMethodCall = MakeMethodCall; this.MakeEqualZero = MakeEqualZero; }
private HashSet <Cmd> FindPredCmds(Block b, ICFG cfg) { HashSet <Cmd> pred_cmds = new HashSet <Cmd>(); List <Block> pred_blocks = cfg.predEdges[b].ToList(); List <Block> visited_blocks = new List <Block> { b }; Block current_block; while (pred_blocks.Any()) { current_block = pred_blocks.First(); pred_blocks.Remove(current_block); if (current_block.Cmds.Any()) { pred_cmds.Add(current_block.Cmds.Last()); } else { pred_blocks.AddRange(cfg.predEdges[current_block].Except(visited_blocks)); } visited_blocks.Add(current_block); } return(pred_cmds); }
public static Dictionary<CFGBlock, List<CFGBlock>> ComputeContainingLoopMap(ICFG cfg) { Contract.Requires(cfg != null); Contract.Ensures(Contract.Result<Dictionary<CFGBlock, List<CFGBlock>>>() != null); var result = new Dictionary<CFGBlock, List<CFGBlock>>(); var visitedSubroutines = new Set<int>(); var pendingSubroutines = new Stack<Subroutine>(); var pendingAPCs = new Stack<APC>(); var graph = cfg.AsBackwardGraph(includeExceptionEdges:false, skipContracts:true); foreach (var loophead in cfg.LoopHeads) { // push back-edge sources var loopPC = new APC(loophead, 0, null); foreach (var pred in cfg.Predecessors(loopPC)) { if (cfg.IsForwardBackEdge(pred, loopPC)) { var normalizedPred = new APC(pred.Block, 0, null); pendingAPCs.Push(normalizedPred); } } var visit = new DepthFirst.Visitor<APC, Unit>(graph, (APC pc) => { if (pc.SubroutineContext != null) { // push continuation PC pendingAPCs.Push(new APC(pc.SubroutineContext.Head.One, 0, null)); if (visitedSubroutines.AddQ(pc.Block.Subroutine.Id)) { pendingSubroutines.Push(pc.Block.Subroutine); } return false; // stop exploration } return !pc.Equals(loopPC); }); while (pendingAPCs.Count > 0) { var root = pendingAPCs.Pop(); visit.VisitSubGraphNonRecursive(root); while (pendingSubroutines.Count > 0) { var sub = pendingSubroutines.Pop(); pendingAPCs.Push(new APC(sub.Exit, 0, null)); } } foreach (var visited in visit.Visited) { if (visited.SubroutineContext != null) continue; // ignore non-primary pcs MaterializeContainingLoop(result, visited.Block).AssumeNotNull().Add(loophead); } } return result; }
public static void Run(Program input, string outputFile) { Implementation impl = input.Implementations.First(); CommandLineOptions.Clo.PruneInfeasibleEdges = true; impl.PruneUnreachableBlocks(); ICFG cfg = new ICFG(impl); EmitCFGGraph(outputFile, cfg); }
public BackwardsPropagation( APC pcCondition, IFactQuery <BoxedExpression, Variable> facts, IMethodDriver <Local, Parameter, Method, Field, Property, Event, Type, Attribute, Assembly, Expression, Variable, LogOptions> mdriver, TimeOutChecker timeout) { Contract.Requires(mdriver != null); this.pcCondition = pcCondition; this.facts = facts; this.Mdriver = mdriver; this.CFG = this.Mdriver.StackLayer.Decoder.Context.MethodContext.CFG; this.timeout = timeout; this.joinPoints = new Dictionary <APC, Preconditions>(); }
public void InstallEntryAssumes(ICFG cfg, IEnumerable <Pair <BoxedExpression, Method> > inferredAssumes, Method method) { Contract.Requires(inferredAssumes != null); foreach (var inferredAssume in inferredAssumes) { var assume = inferredAssume.One; var dummyAPC = cfg.Entry; // TODO: do something better here! we don't know the APC yet, so we just pick some legitimate APC to avoid null ptr deref when looking up src context Provenance provenance = null; var be = new BoxedExpression.AssumeExpression(assume, "assume", dummyAPC, provenance, assume.ToString <Type>(type => OutputPrettyCS.TypeHelper.TypeFullName(this.MetaDataDecoder, type))); var pc = new BoxedExpression.PC(be, 0); this.MethodCache.AddEntryAssume(cfg, method, pc, ClousotExpressionCodeProvider <Local, Parameter, Method, Field, Type> .Decoder); } }
public GenericNecessaryConditionsGenerator( APC pcCondition, IFactQuery <BoxedExpression, Variable> facts, IMethodDriver <Local, Parameter, Method, Field, Property, Event, Type, Attribute, Assembly, Expression, Variable, LogOptions> mdriver, TimeOutChecker timeout) { Contract.Requires(mdriver != null); this.pcCondition = pcCondition; this.facts = facts; this.Mdriver = mdriver; this.CFG = this.Mdriver.StackLayer.Decoder.Context.MethodContext.CFG; this.underVisit = new Set <APC>(); this.timeout = timeout; this.ExpressionReader = new ExpressionReader <Local, Parameter, Method, Field, Property, Event, Type, Attribute, Assembly, Expression, Variable>(); this.SatisfyProcedure = new SimpleSatisfyProcedure <Local, Parameter, Method, Field, Property, Event, Type, Attribute, Assembly>(mdriver.MetaDataDecoder); this.LoopHit = false; this.mutator = new ReplaceSymbolicValueForAccessPath <Local, Parameter, Method, Field, Property, Event, Type, Variable, Expression, Attribute, Assembly>(mdriver.Context, mdriver.MetaDataDecoder); }
public ForwardAnalysis(ICFG cfg, Func <APC, AbstractState, AbstractState> transfer, Joiner <APC, AbstractState> joiner, Func <AbstractState, AbstractState> immutableVersion, Func <AbstractState, AbstractState> mutableVersion, EdgeConverter <APC, AbstractState, EdgeData> edgeConverter, Func <APC, APC, EdgeData> edgeDataGetter, Func <APC, AbstractState, bool> isBottom, Action <Pair <AbstractState, TextWriter> > dumper) : base(cfg) { this.transfer = transfer; this.joiner = joiner; this.immutable_version = immutableVersion; this.mutable_version = mutableVersion; this.edge_converter = edgeConverter; this.edge_data_getter = edgeDataGetter; this.is_bottom = isBottom; this.dumper = dumper; }
private static void EmitCFGGraph(string file, ICFG cfg) { using (System.IO.StreamWriter writer = new System.IO.StreamWriter(file)) { /* Document setup */ writer.WriteLine("digraph slash_conf_assert_graph {"); /* Emitting Nodes */ foreach (Block b in cfg.nodes) { writer.Write("\t"); writer.Write(b.Label); HashSet <string> blockMemoryWrites = GatherMemoryAccesses(b); if (blockMemoryWrites.Count > 1) { writer.Write("[style=wedged,fillcolor=\"" + String.Join(":", blockMemoryWrites) + "\"]"); } else if (blockMemoryWrites.Count == 1) { writer.Write("[style=filled, color=" + blockMemoryWrites.First() + "]"); } else if (b.Cmds.Count == 0) { writer.Write("[style=filled, color=black, fontcolor=white]"); } writer.Write(";\n"); } /* Emitting Links */ foreach (Block b in cfg.nodes) { foreach (Block succ in cfg.succEdges[b]) { writer.Write(b.Label + "->" + succ.Label + ";\n"); } } /* Emitting Document end */ writer.Write("}"); writer.Close(); } }
public ForwardAnalysisSolver( ICFG cfg, Transformer <APC, AState, AState> transfer, EdgeConverter <APC, AState, EdgeData> edgeConverter, Joiner <APC, AState> joiner, Converter <AState, AState> immutableVersion, Converter <AState, AState> mutableVersion, Action <Pair <AState, TextWriter> > dumper, Func <APC, AState, bool> isBottom, Func <APC, AState, bool> isTop, ILPrinter <APC> printer, Printer <EdgeData> edgeDataPrinter, Func <APC, APC, EdgeData> edgeDataGetter ) : base(cfg) { Contract.Requires(transfer != null); Contract.Requires(immutableVersion != null); Contract.Requires(isBottom != null); Contract.Requires(isTop != null); Contract.Requires(joiner != null); Contract.Requires(mutableVersion != null); Contract.Requires(edgeConverter != null); Contract.Requires(edgeDataGetter != null); this.transfer = transfer; this.edgeConverter = edgeConverter; this.joiner = joiner; this.immutableVersion = immutableVersion; this.mutableVersion = mutableVersion; this.dumper = dumper; this.isBottom = isBottom; this.isTop = isTop; this.printer = printer; this.edgeDataPrinter = edgeDataPrinter; this.edgeDataGetter = edgeDataGetter; }
private void PerformTaintAnalysisAlternate() { bool fixed_point = false; ICFG cfg = new ICFG(this.impl); while (!fixed_point) { fixed_point = true; foreach (Block b in this.impl.Blocks.AsEnumerable().Reverse()) { if (!b.Cmds.Any()) { continue; } fixed_point &= !PerformCommandAnalysis(b.Cmds); foreach (Cmd pred_cmd in FindPredCmds(b, cfg)) { fixed_point &= !PerformCommandAnalysis(new List <Cmd> { pred_cmd, b.Cmds.First() }); } } } }
public static Dictionary <CFGBlock, List <CFGBlock> > ComputeContainingLoopMap(ICFG cfg) { Contract.Requires(cfg != null); Contract.Ensures(Contract.Result <Dictionary <CFGBlock, List <CFGBlock> > >() != null); var result = new Dictionary <CFGBlock, List <CFGBlock> >(); var visitedSubroutines = new Set <int>(); var pendingSubroutines = new Stack <Subroutine>(); var pendingAPCs = new Stack <APC>(); var graph = cfg.AsBackwardGraph(includeExceptionEdges: false, skipContracts: true); foreach (var loophead in cfg.LoopHeads) { // push back-edge sources var loopPC = new APC(loophead, 0, null); foreach (var pred in cfg.Predecessors(loopPC)) { if (cfg.IsForwardBackEdge(pred, loopPC)) { var normalizedPred = new APC(pred.Block, 0, null); pendingAPCs.Push(normalizedPred); } } var visit = new DepthFirst.Visitor <APC, Unit>(graph, (APC pc) => { if (pc.SubroutineContext != null) { // push continuation PC pendingAPCs.Push(new APC(pc.SubroutineContext.Head.One, 0, null)); if (visitedSubroutines.AddQ(pc.Block.Subroutine.Id)) { pendingSubroutines.Push(pc.Block.Subroutine); } return(false); // stop exploration } return(!pc.Equals(loopPC)); }); while (pendingAPCs.Count > 0) { var root = pendingAPCs.Pop(); visit.VisitSubGraphNonRecursive(root); while (pendingSubroutines.Count > 0) { var sub = pendingSubroutines.Pop(); pendingAPCs.Push(new APC(sub.Exit, 0, null)); } } foreach (var visited in visit.Visited) { if (visited.SubroutineContext != null) { continue; // ignore non-primary pcs } MaterializeContainingLoop(result, visited.Block).AssumeNotNull().Add(loophead); } } return(result); }
protected ForwardDataFlowAnalysisBase(ICFG cfg) : base(cfg) { }
public ContractFilteredCFG (ICFG cfg) { this.underlying = cfg; }
/// <summary> /// Responsibility to make sure the assume can be properly decoded lies with the serializer/deserializer. /// The SER/DES should have enough detail and checks to make sure a deserialized expression can be decoded without /// failing due to stack mismatch or failed type assumptions. /// </summary> public void InstallCalleeAssumes(ICFG cfg, IEnumerable <Pair <BoxedExpression, Method> > inferredAssumes, Method method) { Contract.Requires(inferredAssumes != null); #if false if (!inferredAssumes.Any()) { return; } //this.Output.WriteLine("Trying to install {0} inferred assumes.", inferredAssumes.Count); // We lookup by name var locs = this.MetaDataDecoder.Locals(method).Enumerate().Select(local => this.MetaDataDecoder.Name(local)); var paramz = this.MetaDataDecoder.Parameters(method).Enumerate().Select(parameter => this.MetaDataDecoder.Name(parameter)); var fields = this.MetaDataDecoder.Fields(this.MetaDataDecoder.DeclaringType(method)).Select(m => this.MetaDataDecoder.Name(method)); #endif // TODO: can the name / expr matching get mixed up during deserialization? foreach (var inferredAssume in inferredAssumes) { var assume = inferredAssume.One; //this.Output.WriteLine("Installing assume " + assume); #if false #region Ensure that all var's in the assume expression still exist in the new version of the function // Check that the variables appearing in the assume to install exists in the scope. // We use the name of the variables to make sure they are the same variable var foundAllVariables = assume.Variables().TrueForAll(v => { var vToString = v.ToString(); // check for var in locs var found = locs.Any(loc => vToString == loc); // check for var in params found = found || paramz.Any(param => vToString == param); //string paramStr = this.MetaDataDecoder.ParameterType(paramz[j]) + " " + v.ToString(); // create str with same format as parameter string; hacky, but needed // check for var in fields found = found || fields.Any(fName => { return(vToString == fName || // "normal" case vToString == String.Format("this.{0}", fName)); // case where field prefixed with "this" }); return(found); }); if (!foundAllVariables) { continue; } #endregion // found all locals, going to try to install this assume #endif var dummyAPC = cfg.Entry; // TODO: do something better here! we don't know the APC yet, so we just pick some legitimate APC to avoid null ptr deref when looking up src context Provenance provenance = null; var be = new BoxedExpression.AssumeExpression(assume, "assume", dummyAPC, provenance, assume.ToString <Type>(type => OutputPrettyCS.TypeHelper.TypeFullName(this.MetaDataDecoder, type))); var pc = new BoxedExpression.PC(be, 0); var calleeName = inferredAssume.Two; this.MethodCache.AddCalleeAssumeAsPostCondition(cfg, method, calleeName, pc, ClousotExpressionCodeProvider <Local, Parameter, Method, Field, Type> .Decoder); } }
public ContractFilteredCFG(ICFG underlying) { Contract.Requires(underlying != null); this.underlying = underlying; }
protected BackwardDFA(ICFG cfg, bool skipContracts) : base(cfg) { this.skipContracts = skipContracts; }
protected ForwardDFA(ICFG cfg) : base(cfg) { }
protected DFARootContract(ICFG cfg) : base(cfg) { }
private static void EmitCFGGraph(string file, ICFG cfg) { using (System.Xml.XmlTextWriter writer = new System.Xml.XmlTextWriter(file, Encoding.UTF8)) { /* Document setup */ writer.WriteStartDocument(true); writer.Formatting = System.Xml.Formatting.Indented; writer.Indentation = 2; writer.WriteStartElement("DirectedGraph", @"http://schemas.microsoft.com/vs/2009/dgml"); /* Emitting Nodes */ writer.WriteStartElement("Nodes"); foreach (Block b in cfg.nodes) { writer.WriteStartElement("Node"); writer.WriteAttributeString("Id", b.Label); HashSet <MemoryOperation> blockMemoryWrites = GatherMemoryAccesses(b); if (blockMemoryWrites.Any()) { writer.WriteAttributeString("Group", "Expanded"); } if (!b.Cmds.Any()) { writer.WriteAttributeString("Background", "Black"); writer.WriteAttributeString("Foreground", "White"); } else if (blockMemoryWrites.Contains(MemoryOperation.CALL)) { writer.WriteAttributeString("Background", "Brown"); } else if (blockMemoryWrites.Contains(MemoryOperation.STORE_BITMAP)) { writer.WriteAttributeString("Background", "Blue"); } else if (blockMemoryWrites.Contains(MemoryOperation.STORE_STACK)) { writer.WriteAttributeString("Background", "Red"); } else if (blockMemoryWrites.Contains(MemoryOperation.STORE_REST)) { writer.WriteAttributeString("Background", "Green"); } writer.WriteEndElement(); } writer.WriteEndElement(); /* Emitting Links */ writer.WriteStartElement("Links"); foreach (Block b in cfg.nodes) { foreach (Block succ in cfg.succEdges[b]) { writer.WriteStartElement("Link"); writer.WriteAttributeString("Source", b.Label); writer.WriteAttributeString("Target", succ.Label); writer.WriteEndElement(); } foreach (MemoryOperation ml in GatherMemoryAccesses(b)) { writer.WriteStartElement("Link"); writer.WriteAttributeString("Source", b.Label); writer.WriteAttributeString("Target", b.Label + "_" + ml); writer.WriteAttributeString("Category", "Contains"); writer.WriteEndElement(); } } writer.WriteEndElement(); /* Emitting DirectedGraph end */ writer.WriteEndElement(); /* Emitting Document end */ writer.WriteEndDocument(); } }
public ContractFilteredCFG(ICFG cfg) { this.underlying = cfg; }