Esempio n. 1
0
        public void ExceptionHandlerWithPrologueAndEpilogue()
        {
            var ranges = new[]
            {
                new ExceptionHandlerRange(
                    new AddressRange(1, 3),
                    new AddressRange(3, 5),
                    new AddressRange(5, 7),
                    new AddressRange(7, 9))
            };

            var instructions = new[]
            {
                DummyInstruction.Op(0, 0, 0),

                // try start
                DummyInstruction.Op(1, 0, 0),
                DummyInstruction.Jmp(2, 9),

                // handler prologue start
                DummyInstruction.Op(3, 0, 0),
                DummyInstruction.Ret(4),

                // handler start
                DummyInstruction.Op(5, 0, 0),
                DummyInstruction.Jmp(6, 9),

                // handler epilogue start
                DummyInstruction.Op(7, 0, 0),
                DummyInstruction.Ret(8),

                DummyInstruction.Ret(9),
            };

            var cfg       = ConstructGraphWithEHRegions(instructions, ranges);
            var rootScope = cfg.ConstructBlocks();

            Assert.Equal(3, rootScope.Blocks.Count);
            var ehBlock = Assert.IsAssignableFrom <ExceptionHandlerBlock <DummyInstruction> >(rootScope.Blocks[1]);

            Assert.Equal(new[] { 1L }, ehBlock.ProtectedBlock.GetAllBlocks().Select(b => b.Offset));
            var handlerBlock = Assert.Single(ehBlock.Handlers);

            Assert.NotNull(handlerBlock);
            Assert.Equal(new[] { 3L }, handlerBlock.Prologue.GetAllBlocks().Select(b => b.Offset));
            Assert.Equal(new[] { 5L }, handlerBlock.Contents.GetAllBlocks().Select(b => b.Offset));
            Assert.Equal(new[] { 7L }, handlerBlock.Epilogue.GetAllBlocks().Select(b => b.Offset));
        }
Esempio n. 2
0
        public void RootNodesShouldHaveNoParent()
        {
            var ast = ConstructAst(new[]
            {
                DummyInstruction.Push(0, 1),
                DummyInstruction.Push(1, 2),
                DummyInstruction.Op(2, 2, 1),
                DummyInstruction.Op(3, 2, 0),
                DummyInstruction.Ret(4)
            });

            Assert.Single(ast.Nodes);
            var block = ast.Entrypoint.Contents.Instructions;

            Assert.Equal(5, block.Count);
            Assert.All(block, node => Assert.Null(node.Parent));
        }
        public void JumpBackToFarBlock()
        {
            var instructions = new[]
            {
                DummyInstruction.Pop(0, 1),
                DummyInstruction.Ret(1),

                DummyInstruction.Push(100, 1),
                DummyInstruction.Jmp(101, 0),
            };

            var(cfg, dfg) = BuildFlowGraphs(instructions, 100);

            Assert.Equal(new[]
            {
                0L, 100L
            }, cfg.Nodes.Select(n => n.Offset));
        }
        public void JoiningPathsWithDifferentStackHeightsShouldThrow()
        {
            var instructions = new[]
            {
                DummyInstruction.Push(0, 1),
                DummyInstruction.JmpCond(1, 4),

                DummyInstruction.Push(2, 2),
                DummyInstruction.Jmp(3, 5),

                DummyInstruction.Push(4, 1),

                DummyInstruction.Pop(5, 1),
                DummyInstruction.Ret(6)
            };

            Assert.Throws <StackImbalanceException>(() => BuildFlowGraphs(instructions));
        }
Esempio n. 5
0
        public void JumpForwardToFarBlock()
        {
            var instructions = new[]
            {
                DummyInstruction.Push(0, 1),
                DummyInstruction.Jmp(1, 100),

                DummyInstruction.Pop(100, 1),
                DummyInstruction.Ret(101),
            };

            var graph = BuildControlFlowGraph(instructions);

            Assert.Equal(new[]
            {
                0L, 100L
            }, graph.Nodes.Select(n => n.Offset));
        }
Esempio n. 6
0
        public void SingleBlock()
        {
            var instructions = new[]
            {
                DummyInstruction.Push(0, 1),
                DummyInstruction.Push(1, 1),
                DummyInstruction.Op(2, 2, 1),
                DummyInstruction.Push(3, 1),
                DummyInstruction.Push(4, 1),
                DummyInstruction.Ret(5)
            };

            var graph = BuildControlFlowGraph(instructions);

            Assert.Single(graph.Nodes);
            Assert.Equal(instructions, graph.Nodes.First().Contents.Instructions);
            Assert.Equal(graph.Nodes.First(), graph.Entrypoint);
        }
        public void BranchTargetChangeToAnotherNodeHeaderShouldUpdateFallThroughEdge()
        {
            var cfg = BuildControlFlowGraph(new[]
            {
                DummyInstruction.Op(0, 0, 0),
                DummyInstruction.Jmp(1, 10),

                DummyInstruction.Jmp(10, 20),

                DummyInstruction.Ret(20)
            });

            // Change branch target of the first jmp to the ret at offset 20.
            cfg.Nodes[0].Contents.Footer.Operands[0] = 20L;

            Assert.True(cfg.UpdateFlowControl(DummyArchitecture.Instance.SuccessorResolver));
            Assert.Same(cfg.Nodes[20], cfg.Nodes[0].FallThroughNeighbour);
        }
        public void BlockHeadersImpliedByInstructionsShouldAlwaysBeAdded()
        {
            var instructions = new[]
            {
                DummyInstruction.PushOffset(0, 10),
                DummyInstruction.Ret(1),

                DummyInstruction.Op(10, 0, 0),
                DummyInstruction.Ret(11),
            };

            var(cfg, _) = BuildFlowGraphs(instructions);
            Assert.Contains(cfg.Nodes, n => n.Offset == 0);
            Assert.Contains(cfg.Nodes, n => n.Offset == 10);
            Assert.DoesNotContain(cfg.Nodes, n => n.Offset == 1);
            Assert.Empty(cfg.Nodes[0].GetOutgoingEdges());
            Assert.Empty(cfg.Nodes[10].GetIncomingEdges());
        }
Esempio n. 9
0
        public void WeirdOrder()
        {
            var instructions = new[]
            {
                DummyInstruction.Op(0, 0, 0),
                DummyInstruction.Op(1, 0, 0),
                DummyInstruction.Op(2, 0, 0),
                DummyInstruction.Jmp(3, 6),

                DummyInstruction.Op(4, 0, 0),
                DummyInstruction.Ret(5),

                DummyInstruction.Op(6, 0, 0),
                DummyInstruction.Op(7, 0, 0),
                DummyInstruction.Jmp(8, 15),

                DummyInstruction.Op(9, 0, 0),
                DummyInstruction.Op(10, 0, 0),
                DummyInstruction.Jmp(11, 4),

                DummyInstruction.Op(12, 0, 0),
                DummyInstruction.Op(13, 0, 0),
                DummyInstruction.Jmp(14, 9),

                DummyInstruction.Op(15, 0, 0),
                DummyInstruction.Op(16, 0, 0),
                DummyInstruction.Jmp(17, 12),
            };

            var cfgBuilder = new StaticFlowGraphBuilder <DummyInstruction>(
                DummyArchitecture.Instance,
                instructions,
                DummyArchitecture.Instance.SuccessorResolver);

            var cfg          = cfgBuilder.ConstructFlowGraph(0);
            var blockBuilder = new BlockBuilder <DummyInstruction>();
            var rootScope    = blockBuilder.ConstructBlocks(cfg);

            var order = rootScope.GetAllBlocks().ToArray();

            Assert.Equal(
                new long[] { 0, 6, 15, 12, 9, 4 },
                order.Select(b => b.Offset));
        }
Esempio n. 10
0
        public void PushingTwoValuesOnStackShouldResultInTwoVariablesAssigned()
        {
            var cfg = ConstructAst(new[]
            {
                DummyInstruction.Push(0, 2),
                DummyInstruction.Pop(1, 2),
                DummyInstruction.Ret(2)
            });

            var variableCapture  = new CaptureGroup("variable");
            var argumentsCapture = new CaptureGroup("argument");

            var pattern = new SequencePattern <Statement <DummyInstruction> >(
                // stack_slot_1, stack_slot_2 = push 2()
                StatementPattern
                .Assignment <DummyInstruction>()
                .WithVariables(2)
                .CaptureVariables(variableCapture),

                // pop(?, ?)
                StatementPattern.Expression(ExpressionPattern
                                            .Instruction <DummyInstruction>()
                                            .WithArguments(2)
                                            .CaptureArguments(argumentsCapture)),

                // ret()
                StatementPattern.Instruction(new DummyInstructionPattern(DummyOpCode.Ret))
                );

            var result = pattern.Match(cfg.Nodes[0].Contents.Instructions);

            Assert.True(result.IsSuccess);

            var variables = result.Captures[variableCapture]
                            .Cast <IVariable>()
                            .ToArray();

            var arguments = result.Captures[argumentsCapture]
                            .Cast <VariableExpression <DummyInstruction> >()
                            .Select(e => e.Variable)
                            .ToArray();

            Assert.Equal(variables, arguments);
        }
Esempio n. 11
0
        public void MultiplePopsShouldHaveMultipleStackDependencies()
        {
            var instructions = new[]
            {
                DummyInstruction.Push(0, 1),
                DummyInstruction.Push(1, 1),
                DummyInstruction.Push(2, 1),
                DummyInstruction.Pop(3, 3),
                DummyInstruction.Ret(4)
            };

            var(cfg, dfg) = BuildFlowGraphs(instructions);

            Assert.Equal(3, dfg.Nodes[3].StackDependencies.Count);
            Assert.Equal(new[]
            {
                dfg.Nodes[0], dfg.Nodes[1], dfg.Nodes[2],
            }, dfg.Nodes[3].StackDependencies.Select(dep => dep.First().Node));
        }
Esempio n. 12
0
        public void SwitchWithAssignmentsToSameVariableShouldResultInPhiNodeWithTheSameNumberOfSources()
        {
            var variable = new DummyVariable("temp");

            var cfg = ConstructAst(new[]
            {
                // switch(some_value)
                DummyInstruction.Push(0, 1),
                DummyInstruction.Switch(1, 5, 8, 11),

                // default:
                DummyInstruction.Push(2, 1),
                DummyInstruction.Set(3, variable),
                DummyInstruction.Jmp(4, 13),

                // case 0:
                DummyInstruction.Push(5, 1),
                DummyInstruction.Set(6, variable),
                DummyInstruction.Jmp(7, 13),

                // case 1:
                DummyInstruction.Push(8, 1),
                DummyInstruction.Set(9, variable),
                DummyInstruction.Jmp(10, 13),

                // case 2:
                DummyInstruction.Push(11, 1),
                DummyInstruction.Set(12, variable),

                // end:
                DummyInstruction.Get(13, variable),
                DummyInstruction.Pop(14, 1),
                DummyInstruction.Ret(15)
            });

            // variable = phi(?, ?)
            var phiPattern = StatementPattern
                             .Phi <DummyInstruction>()
                             .WithSources(4);

            Assert.True(phiPattern.Matches(cfg.Nodes[13].Contents.Header),
                        "Node 13 was expected to start with a phi node with 4 sources.");
        }
        public void AddBranchInMiddleOfBlockShouldSplit()
        {
            var instructions = new[]
            {
                DummyInstruction.Op(0, 0, 0),
                DummyInstruction.Op(1, 0, 0),
                DummyInstruction.Op(2, 0, 0),
                DummyInstruction.Op(3, 0, 0),
                DummyInstruction.Ret(4),
            };
            var cfg = BuildControlFlowGraph(instructions, 0);

            cfg.Nodes[0].Contents.Instructions[1] = DummyInstruction.Jmp(1, 4);
            cfg.UpdateFlowControl(DummyArchitecture.Instance.SuccessorResolver);

            Assert.True(cfg.Nodes.Contains(0));
            Assert.True(cfg.Nodes.Contains(4));
            Assert.Same(cfg.Nodes[4], cfg.Nodes[0].FallThroughNeighbour);
        }
Esempio n. 14
0
        public void EntryPointPopWithInitialStateEmptyShouldThrow()
        {
            var instructions = new[]
            {
                DummyInstruction.Pop(0, 1),
                DummyInstruction.Ret(1),
            };

            var dfgBuilder = new DummyTransitionResolver
            {
                InitialState = new SymbolicProgramState <DummyInstruction>()
            };

            var cfgBuilder = new SymbolicFlowGraphBuilder <DummyInstruction>(
                DummyArchitecture.Instance,
                instructions,
                dfgBuilder);

            Assert.Throws <StackImbalanceException>(() => cfgBuilder.ConstructFlowGraph(0));
        }
Esempio n. 15
0
        public void ReplacingInstructionInInstructionExpression()
        {
            var ast = ConstructAst(new[]
            {
                DummyInstruction.Push(0, 1),
                DummyInstruction.Pop(1, 1),
                DummyInstruction.Ret(2)
            });

            Assert.Single(ast.Nodes);
            var block = ast.Entrypoint.Contents.Instructions;

            Assert.Equal(3, block.Count);
            Assert.All(block, node => Assert.Null(node.Parent));

            var instruction = DummyInstruction.Jmp(0, 69);
            var asmt        = Assert.IsType <AssignmentStatement <DummyInstruction> >(block[0]);
            var expr        = Assert.IsType <InstructionExpression <DummyInstruction> >(asmt.Expression);

            Assert.Equal(instruction, expr.WithInstruction(instruction).Instruction);
        }
        public void EHWithMultipleHandlersByRangesShouldGroupTogether(bool reverse)
        {
            var ranges = new[]
            {
                new ExceptionHandlerRange(new AddressRange(1, 3), new AddressRange(3, 5)),
                new ExceptionHandlerRange(new AddressRange(1, 3), new AddressRange(5, 7)),
            };

            if (reverse)
            {
                Array.Reverse(ranges);
            }

            var instructions = new[]
            {
                DummyInstruction.Op(0, 0, 0),

                // try start 1 & 2
                DummyInstruction.Op(1, 0, 0),
                DummyInstruction.Jmp(2, 7),

                // handler start 2
                DummyInstruction.Op(3, 0, 0),
                DummyInstruction.Jmp(4, 7),

                // handler start 1
                DummyInstruction.Op(5, 0, 0),
                DummyInstruction.Jmp(6, 7),

                DummyInstruction.Ret(7),
            };

            var cfg = ConstructGraphWithEHRegions(instructions, ranges);

            var ehRegion = cfg.Nodes[1].GetParentExceptionHandler();

            Assert.Same(ehRegion, cfg.Nodes[3].GetParentExceptionHandler());
            Assert.Same(ehRegion, cfg.Nodes[5].GetParentExceptionHandler());
            Assert.NotSame(cfg.Nodes[3].ParentRegion, cfg.Nodes[5].ParentRegion);
        }
Esempio n. 17
0
        public void BasicRegionShouldTranslateToSingleScopeBlock()
        {
            var instructions = new[]
            {
                DummyInstruction.Push(0, 1),
                DummyInstruction.JmpCond(1, 4),

                DummyInstruction.Op(2, 0, 0),
                DummyInstruction.Jmp(3, 4),

                DummyInstruction.Op(4, 0, 0),
                DummyInstruction.Ret(5),
            };

            var cfgBuilder = new StaticFlowGraphBuilder <DummyInstruction>(
                DummyArchitecture.Instance,
                instructions,
                DummyArchitecture.Instance.SuccessorResolver);

            var cfg = cfgBuilder.ConstructFlowGraph(0);

            var region = new BasicControlFlowRegion <DummyInstruction>();

            cfg.Regions.Add(region);
            region.Nodes.Add(cfg.Nodes[2]);

            var blockBuilder = new BlockBuilder <DummyInstruction>();
            var rootScope    = blockBuilder.ConstructBlocks(cfg);

            Assert.Equal(3, rootScope.Blocks.Count);
            Assert.IsAssignableFrom <BasicBlock <DummyInstruction> >(rootScope.Blocks[0]);
            Assert.IsAssignableFrom <ScopeBlock <DummyInstruction> >(rootScope.Blocks[1]);
            Assert.IsAssignableFrom <BasicBlock <DummyInstruction> >(rootScope.Blocks[2]);

            var order = rootScope.GetAllBlocks().ToArray();

            Assert.Equal(
                new long[] { 0, 2, 4 },
                order.Select(b => b.Offset));
        }
        public void SplittedNodeShouldBeRemergedAfterDetectingInvalidFallThroughNeighbour()
        {
            var instructions = new[]
            {
                DummyInstruction.Op(0, 0, 0),
                DummyInstruction.Jmp(1, 10),
                DummyInstruction.Op(10, 0, 0),
                DummyInstruction.Op(11, 0, 0),
                DummyInstruction.Op(12, 0, 0),
                DummyInstruction.Jmp(13, 20),
                DummyInstruction.Ret(20),
            };
            var cfg = BuildControlFlowGraph(instructions, 0);

            instructions[1].Operands[0] = 12L;
            instructions[5].Operands[0] = 100L;

            Assert.Throws <ArgumentException>(() => cfg.UpdateFlowControl(DummyArchitecture.Instance.SuccessorResolver));

            Assert.Same(cfg.Nodes[10], cfg.Nodes[0].FallThroughNeighbour);
            Assert.False(cfg.Nodes.Contains(12));
        }
Esempio n. 19
0
        public void LoopCounterShouldResultInOnlyOnePhiNode()
        {
            var counterVariable = new DummyVariable("i");

            var cfg = ConstructAst(new[]
            {
                // i = initial();
                DummyInstruction.Push(0, 1),
                DummyInstruction.Set(1, counterVariable),

                // loop:
                // if (cond(i)) goto end;
                DummyInstruction.Get(2, counterVariable),
                DummyInstruction.JmpCond(3, 9),

                // Loop body.
                DummyInstruction.Op(4, 0, 0),

                // i = next(i);
                // goto loop
                DummyInstruction.Get(5, counterVariable),
                DummyInstruction.Op(6, 1, 1),
                DummyInstruction.Set(7, counterVariable),
                DummyInstruction.Jmp(8, 2),

                // end:
                DummyInstruction.Ret(9)
            });

            // variable = phi(?, ?)
            var phiPattern = StatementPattern
                             .Phi <DummyInstruction>()
                             .WithSources(2);

            Assert.True(phiPattern.Matches(cfg.Nodes[2].Contents.Header));
            Assert.All(cfg.Nodes[0].Contents.Instructions, s => Assert.False(phiPattern.Matches(s)));
            Assert.All(cfg.Nodes[4].Contents.Instructions, s => Assert.False(phiPattern.Matches(s)));
            Assert.All(cfg.Nodes[9].Contents.Instructions, s => Assert.False(phiPattern.Matches(s)));
        }
Esempio n. 20
0
        public void ReplacingExpressionInStatementShouldChangeParent()
        {
            var ast = ConstructAst(new[]
            {
                DummyInstruction.Push(0, 2),
                DummyInstruction.Pop(1, 2),
                DummyInstruction.Ret(2)
            });

            Assert.Single(ast.Nodes);
            var block = ast.Entrypoint.Contents.Instructions;

            Assert.Equal(3, block.Count);
            Assert.All(block, node => Assert.Null(node.Parent));

            var expr = new InstructionExpression <DummyInstruction>(DummyInstruction.Jmp(0, 69),
                                                                    Array.Empty <Expression <DummyInstruction> >());
            var stmt = Assert.IsType <ExpressionStatement <DummyInstruction> >(block[1]);

            Assert.Equal(expr, stmt.WithExpression(expr).Expression);
            Assert.Equal(stmt, expr.Parent);
        }
Esempio n. 21
0
        public static ControlFlowGraph <DummyInstruction> CreateIf()
        {
            var graph = new ControlFlowGraph <DummyInstruction>(DummyArchitecture.Instance);

            var n1 = new ControlFlowNode <DummyInstruction>(0,
                                                            DummyInstruction.Op(0, 0, 1),
                                                            DummyInstruction.JmpCond(1, 3));

            var n2 = new ControlFlowNode <DummyInstruction>(2,
                                                            DummyInstruction.Op(2, 0, 0));

            var n3 = new ControlFlowNode <DummyInstruction>(3,
                                                            DummyInstruction.Ret(3));

            graph.Nodes.AddRange(new[] { n1, n2, n3 });
            graph.Entrypoint = n1;

            n1.ConnectWith(n2);
            n1.ConnectWith(n3, ControlFlowEdgeType.Conditional);
            n2.ConnectWith(n3);

            return(graph);
        }
Esempio n. 22
0
        public void FlatGraphShouldProduceFlatBlock()
        {
            var instructions = new[]
            {
                DummyInstruction.Op(0, 0, 0),
                DummyInstruction.Op(1, 0, 0),
                DummyInstruction.Op(2, 0, 0),
                DummyInstruction.Op(3, 0, 0),
                DummyInstruction.Ret(4),
            };

            var cfgBuilder = new StaticFlowGraphBuilder <DummyInstruction>(
                DummyArchitecture.Instance,
                instructions,
                DummyArchitecture.Instance.SuccessorResolver);

            var cfg       = cfgBuilder.ConstructFlowGraph(0);
            var rootScope = cfg.ConstructBlocks();

            Assert.Single(rootScope.Blocks);
            Assert.IsAssignableFrom <BasicBlock <DummyInstruction> >(rootScope.Blocks[0]);
            Assert.Equal(instructions, ((BasicBlock <DummyInstruction>)rootScope.Blocks[0]).Instructions);
        }
Esempio n. 23
0
        public static ControlFlowGraph <DummyInstruction> CreateIfElseNested()
        {
            var graph = new ControlFlowGraph <DummyInstruction>(DummyArchitecture.Instance);

            var n1 = new ControlFlowNode <DummyInstruction>(0,
                                                            DummyInstruction.Op(0, 0, 1),
                                                            DummyInstruction.JmpCond(1, 7));

            var n2 = new ControlFlowNode <DummyInstruction>(2,
                                                            DummyInstruction.Op(2, 0, 1),
                                                            DummyInstruction.JmpCond(3, 4));

            var n3 = new ControlFlowNode <DummyInstruction>(4,
                                                            DummyInstruction.Jmp(4, 6));

            var n4 = new ControlFlowNode <DummyInstruction>(5,
                                                            DummyInstruction.Jmp(5, 6));

            var n5 = new ControlFlowNode <DummyInstruction>(6,
                                                            DummyInstruction.Jmp(6, 7));

            var n6 = new ControlFlowNode <DummyInstruction>(7,
                                                            DummyInstruction.Ret(7));

            graph.Nodes.AddRange(new[] { n1, n2, n3, n4, n5, n6 });
            graph.Entrypoint = n1;

            n1.ConnectWith(n2);
            n1.ConnectWith(n6, ControlFlowEdgeType.Conditional);
            n2.ConnectWith(n3);
            n2.ConnectWith(n4, ControlFlowEdgeType.Conditional);
            n3.ConnectWith(n5);
            n4.ConnectWith(n5);
            n5.ConnectWith(n6);

            return(graph);
        }
Esempio n. 24
0
        public void EHWithMultipleHandlersByRangesShouldGroupTogether()
        {
            var ranges = new[]
            {
                new ExceptionHandlerRange(new AddressRange(1, 3), new AddressRange(3, 5)),
                new ExceptionHandlerRange(new AddressRange(1, 3), new AddressRange(5, 7)),
            };

            var instructions = new[]
            {
                DummyInstruction.Op(0, 0, 0),

                // try start 1 & 2
                DummyInstruction.Op(1, 0, 0),
                DummyInstruction.Jmp(2, 7),

                // handler start 2
                DummyInstruction.Op(3, 0, 0),
                DummyInstruction.Jmp(4, 7),

                // handler start 1
                DummyInstruction.Op(5, 0, 0),
                DummyInstruction.Jmp(6, 7),

                DummyInstruction.Ret(7),
            };

            var cfg          = ConstructGraphWithEHRegions(instructions, ranges);
            var blockBuilder = new BlockBuilder <DummyInstruction>();
            var rootScope    = blockBuilder.ConstructBlocks(cfg);

            var order = rootScope.GetAllBlocks().ToArray();

            Assert.Equal(3, rootScope.Blocks.Count);
            Assert.IsAssignableFrom <ExceptionHandlerBlock <DummyInstruction> >(rootScope.Blocks[1]);
            Assert.Equal(2, ((ExceptionHandlerBlock <DummyInstruction>)rootScope.Blocks[1]).HandlerBlocks.Count);
        }
        public void SwapUnconditionalWithConditionalBranchShouldUpdateFallThroughAndConditionalEdge()
        {
            var cfg = BuildControlFlowGraph(new[]
            {
                DummyInstruction.Push(0, 1),
                DummyInstruction.Jmp(1, 10),

                DummyInstruction.Jmp(2, 20),

                DummyInstruction.Jmp(10, 2),

                DummyInstruction.Ret(20)
            }, 0);

            // Update unconditional jmp to a conditional one.
            var blockInstructions = cfg.Nodes[0].Contents.Instructions;

            blockInstructions[blockInstructions.Count - 1] = DummyInstruction.JmpCond(1, 20);

            Assert.True(cfg.UpdateFlowControl(DummyArchitecture.Instance.SuccessorResolver));
            Assert.Same(cfg.Nodes[2], cfg.Nodes[0].FallThroughNeighbour);
            Assert.Single(cfg.Nodes[0].ConditionalEdges);
            Assert.True(cfg.Nodes[0].ConditionalEdges.Contains(cfg.Nodes[20]));
        }
Esempio n. 26
0
        public void BranchingPathsShouldCopyDependency()
        {
            var instructions = new[]
            {
                DummyInstruction.Push(0, 1),

                DummyInstruction.Push(1, 1),
                DummyInstruction.JmpCond(2, 5),

                DummyInstruction.Pop(3, 1),
                DummyInstruction.Jmp(4, 6),

                DummyInstruction.Pop(5, 1),

                DummyInstruction.Ret(6)
            };

            var(cfg, dfg) = BuildFlowGraphs(instructions);

            Assert.Single(dfg.Nodes[3].StackDependencies);
            Assert.Equal(dfg.Nodes[0], dfg.Nodes[3].StackDependencies[0].First().Node);
            Assert.Single(dfg.Nodes[5].StackDependencies);
            Assert.Equal(dfg.Nodes[0], dfg.Nodes[5].StackDependencies[0].First().Node);
        }
Esempio n. 27
0
        public void ReplacingVariablesInAssignmentShouldGetRidOfOldOnes()
        {
            var var1 = new DummyVariable("1");
            var ast  = ConstructAst(new[]
            {
                DummyInstruction.Push(0, 1),
                DummyInstruction.Set(1, var1),
                DummyInstruction.Ret(2),
            });

            Assert.Single(ast.Nodes);
            var block = ast.Entrypoint.Contents.Instructions;

            Assert.Equal(3, block.Count);
            Assert.All(block, node => Assert.Null(node.Parent));

            var var2 = new DummyVariable("2");
            var var3 = new DummyVariable("3");
            var asmt = Assert.IsType <AssignmentStatement <DummyInstruction> >(block[1]);

            Assert.Equal(2, asmt.WithVariables(var2, var3).Variables.Count);
            Assert.Equal(asmt.Variables[0], var2);
            Assert.Equal(asmt.Variables[1], var3);
        }
        public void TestComplexCapture()
        {
            var valueExpression = new InstructionExpression <DummyInstruction>(DummyInstruction.Push(0, 1),
                                                                               ArraySegment <Expression <DummyInstruction> > .Empty);

            var statement = new ExpressionStatement <DummyInstruction>(new InstructionExpression <DummyInstruction>(DummyInstruction.Ret(1), new List <Expression <DummyInstruction> >
            {
                valueExpression
            }));

            // Define capture group.
            var returnValueGroup = new CaptureGroup("returnValue");

            // Create ret(?) pattern.
            var pattern = StatementPattern.Expression(
                ExpressionPattern
                .Instruction(new DummyInstructionPattern(DummyOpCode.Ret))
                .WithArguments(
                    ExpressionPattern.Any <DummyInstruction>().CaptureAs(returnValueGroup)
                    )
                );

            // Match.
            var result = pattern.Match(statement);

            // Extract return expression node.
            var capturedObject = result.Captures[returnValueGroup][0];

            Assert.Same(valueExpression, capturedObject);
        }
Esempio n. 29
0
        public void JoiningPathsWithMultipleAssignmentsShouldOnlyUseLatestVersion()
        {
            var variable = new DummyVariable("temp");

            var cfg = ConstructAst(new[]
            {
                // if (cond) goto else:
                DummyInstruction.Push(0, 1),
                DummyInstruction.JmpCond(1, 7),

                // temp = some_value (not used).
                DummyInstruction.Push(2, 1),
                DummyInstruction.Set(3, variable),
                // temp = some_value (render previous value useless)
                DummyInstruction.Push(4, 1),
                DummyInstruction.Set(5, variable),

                // goto end
                DummyInstruction.Jmp(6, 9),

                // else:
                // temp = some_value
                DummyInstruction.Push(7, 1),
                DummyInstruction.Set(8, variable),

                // end:
                // pop(temp)
                DummyInstruction.Get(9, variable),
                DummyInstruction.Pop(10, 1),

                // return
                DummyInstruction.Ret(11)
            });

            var phiSourcesCapture = new CaptureGroup("sources");
            var variablesCapture  = new CaptureGroup("variables");

            // variable = phi(?, ?)
            var phiPattern = StatementPattern
                             .Phi <DummyInstruction>()
                             .WithSources(2)
                             .CaptureSources(phiSourcesCapture);

            // temp_vx = set(?)
            var assignPattern = StatementPattern
                                .Assignment <DummyInstruction>()
                                .WithExpression(ExpressionPattern
                                                .Instruction(new DummyInstructionPattern(DummyOpCode.Set))
                                                .WithArguments(1))
                                .CaptureVariables(variablesCapture);

            var assignment1Results = assignPattern
                                     .FindAllMatches(cfg.Nodes[7].Contents.Instructions)
                                     .ToArray();

            var assignment2Results = assignPattern
                                     .FindAllMatches(cfg.Nodes[2].Contents.Instructions)
                                     .ToArray();

            var phiResult = phiPattern.Match(cfg.Nodes[9].Contents.Header);

            Assert.True(assignment1Results.Length == 1, "Node 7 was expected to have one assignment to 'temp'.");
            Assert.True(assignment2Results.Length == 2, "Node 2 was expected to have two assignments to 'temp'.");
            Assert.True(phiResult.IsSuccess, "Node 9 was expected to start with a phi node with two sources.");

            var sources = phiResult.Captures[phiSourcesCapture]
                          .Cast <VariableExpression <DummyInstruction> >()
                          .Select(s => s.Variable);

            var allVariables = new[]
            {
                (IVariable)assignment1Results[0].Captures[variablesCapture][0],
                (IVariable)assignment2Results[1].Captures[variablesCapture][0]
            };

            Assert.Equal(allVariables.ToHashSet(), sources.ToHashSet());
        }
Esempio n. 30
0
 private static DataFlowNode <DummyInstruction> CreateDummyNode(long id)
 {
     return(new DataFlowNode <DummyInstruction>(id, DummyInstruction.Op(id, 0, 1)));
 }