public override Implementation VisitImplementation(Implementation node) { LoopDetector loopDetector = new LoopDetector(); loopDetector.Visit(node); this.blocksWithinNautralLoops = loopDetector.getBlocksInNaturalLoops(); this.visit_happened = true; return(base.VisitImplementation(node)); }
private static void InstrumentEnclave( Program prog, Implementation impl, Dictionary <Tuple <string, Cmd, AssertCmd>, bool> storeAddressRegionDB, Dictionary <Tuple <string, Cmd, AssertCmd>, bool> loadAddressRegionDB) { Console.WriteLine("CfiVerifier found " + impl.Blocks.Count + " basic blocks"); (new SpecialInstructionLifter()).Visit(prog); // (new ConstantExpressionSimplifier()).Visit(prog); Utils.PrintProg(prog); if (Options.splitMemoryModel) { (new SplitMemoryModeler(storeAddressRegionDB, loadAddressRegionDB, false)).Visit(prog); (new HavocingLoader()).Visit(prog); } Utils.PrintProg(prog); (new ModularVerificationSetup()).Visit(prog); Utils.PrintProg(prog); //(new Utils.DeadCodeEliminator()).Visit(prog); //mostly to remove assingments to useless CPU flags //if (Utils.verbosityLevel(2)) { Console.WriteLine("InstrumentEnclave: replacing call instructions with CallCmd"); } // (new Utils.HavocingAdversary()).Visit(impl); //FIXME: this should be enabled. LoopDetector loopDetector = new LoopDetector(); loopDetector.Visit(impl); //necessary before querying the stack size estimate List <Block> blocksInNaturalLoops = loopDetector.getBlocksInNaturalLoops(); if (blocksInNaturalLoops.Count > 0) { Console.WriteLine("CfiVerifier found one or more loops"); Console.WriteLine("Blocks in loops: {0}", blocksInNaturalLoops.MapConcat(x => x.Label, ",")); } List <Block> loopHeaders = loopDetector.getLoopHeaders(); if (loopHeaders.Count > 0) { Console.WriteLine("LOOP HEADERS: {0}", loopHeaders.MapConcat(x => x.Label, ",")); Tuple <String, List <String> > result = Utils.HandleLoops(prog, impl); String memCheckpointLabel = result.Item1; List <String> loopHeaderLabels = result.Item2; Utils.InstrumentLoopInvariant(prog, impl, memCheckpointLabel, loopHeaderLabels); } VCSplitter.LaunchVCSplitter(impl); (new EnvironmentSetup()).Visit(prog); //TODO move this earlier, maybe before DeadCodeEliminator (new ProofObligations()).Visit(prog); Console.WriteLine("\nInstrumented Program with CFI assertions and generated output file {0}", Options.instrumentedFile); Utils.PrintProg(prog); VCSplitter.Instance.PrintInstrumentedProcedures(prog); VCSplitter.Instance.PrintAssertionTypes(); }
public static Tuple <String, List <String> > HandleLoops(Program prog, Implementation impl) { LoopDetector loopDetector = new LoopDetector(); loopDetector.Visit(impl); //necessary before querying the stack size estimate List <Block> blocksInNaturalLoops = loopDetector.getBlocksInNaturalLoops(); List <Block> loopHeaders = loopDetector.getLoopHeaders(); List <String> loopHeaderLabels = new List <string>(); loopHeaders.Iter(l => loopHeaderLabels.Add(l.Label)); //if (loopHeaders.Count > 0) { Console.WriteLine("LOOP HEADERS: {0}", loopHeaders.MapConcat(x => x.Label, ",")); } var graph = Program.GraphFromImpl(impl); //Utils.Assert(graph.Reducible, "Irreducible flow graphs are unsupported."); Utils.Assert(graph.Nodes.Count() > 1, "Doesn't work for graphs with 1 node"); //figure out the source node. that's where the program starts. IEnumerable <Block> sourceNodes = graph.Nodes.Where(n => graph.Predecessors(n).Count() == 0); //Also assert that there is only one source node (unless there is unreachable node in the CFG) Utils.Assert(sourceNodes.Count() == 1); Block sourceNode = sourceNodes.ElementAt(0); //Console.WriteLine("SOURCE NODE: {0}", sourceNode.Label); //traverse starting from source node until you get nondeterministic goto, or a loop header Block currentNode = sourceNode; while (graph.Successors(currentNode).Count() < 2) { IEnumerable <Block> successors = graph.Successors(currentNode); //we know this is a loopy program, so we should not get to a sink node in this loop. Utils.Assert(successors.Count() > 0, "We got to a sink node. why???"); Block nextNode = successors.ElementAt(0); //encountered a loop header before a CFG split? if (loopHeaderLabels.Contains(nextNode.Label)) { break; } currentNode = nextNode; } //Console.WriteLine("We should capture mem here: {0}", currentNode.Label); return(new Tuple <string, List <string> >(currentNode.Label, loopHeaderLabels)); }