예제 #1
0
        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));
        }
예제 #2
0
        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();
        }
예제 #3
0
        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));
        }