Exemple #1
0
        public void AddingRegionSecondTimeShouldThrow()
        {
            var graph  = new ControlFlowGraph <int>(IntArchitecture.Instance);
            var region = new BasicControlFlowRegion <int>();

            graph.Regions.Add(region);

            Assert.Throws <ArgumentException>(() => graph.Regions.Add(region));
        }
Exemple #2
0
        public void AddSubRegionShouldSetParentRegion()
        {
            var graph  = new ControlFlowGraph <int>(IntArchitecture.Instance);
            var region = new BasicControlFlowRegion <int>();

            Assert.Null(region.ParentRegion);
            graph.Regions.Add(region);
            Assert.Same(graph, region.ParentRegion);
        }
Exemple #3
0
        private static Dictionary <AddressRange, BasicControlFlowRegion <TInstruction> > CreateEHRegions <TInstruction>(
            ControlFlowGraph <TInstruction> cfg,
            IReadOnlyList <ExceptionHandlerRange> sortedRanges)
        {
            var rangeToRegion = new Dictionary <AddressRange, BasicControlFlowRegion <TInstruction> >();

            var ehRegions = new Dictionary <AddressRange, ExceptionHandlerRegion <TInstruction> >();

            for (int i = 0; i < sortedRanges.Count; i++)
            {
                var currentEHRange = sortedRanges[i];
                if (!ehRegions.TryGetValue(currentEHRange.ProtectedRange, out var ehRegion))
                {
                    // Register new EH region for the protected range.
                    ehRegion = new ExceptionHandlerRegion <TInstruction>();
                    ehRegions.Add(currentEHRange.ProtectedRange, ehRegion);
                    rangeToRegion.Add(currentEHRange.ProtectedRange, ehRegion.ProtectedRegion);

                    // Since the ranges are sorted by enclosing EHs first, we can backtrack the list of ranges to find.
                    // the parent region (if there is any).
                    BasicControlFlowRegion <TInstruction> parentRegion = null;
                    for (int j = i; j >= 0 && parentRegion is null; j--)
                    {
                        var potentialParentRange = sortedRanges[j];
                        if (potentialParentRange.ProtectedRange.Contains(currentEHRange.ProtectedRange))
                        {
                            parentRegion = rangeToRegion[potentialParentRange.ProtectedRange];
                        }
                        if (potentialParentRange.HandlerRange.Contains(currentEHRange.HandlerRange))
                        {
                            parentRegion = rangeToRegion[potentialParentRange.HandlerRange];
                        }
                    }

                    // Insert region into graph or parent region.
                    if (parentRegion is null)
                    {
                        cfg.Regions.Add(ehRegion);
                    }
                    else
                    {
                        parentRegion.Regions.Add(ehRegion);
                    }
                }

                // Register handler region.
                var handlerRegion = new BasicControlFlowRegion <TInstruction>();
                handlerRegion.Tag = currentEHRange.UserData;
                ehRegion.HandlerRegions.Add(handlerRegion);
                rangeToRegion.Add(currentEHRange.HandlerRange, handlerRegion);
            }

            return(rangeToRegion);
        }
Exemple #4
0
        public void AddNodeToNotAddedRegionShouldThrow()
        {
            var graph = new ControlFlowGraph <int>(IntArchitecture.Instance);
            var node  = new ControlFlowNode <int>(0);

            graph.Nodes.Add(node);

            var region = new BasicControlFlowRegion <int>();

            Assert.Throws <InvalidOperationException>(() => region.Nodes.Add(node));
        }
Exemple #5
0
        public void AddNodeNotAddedToGraphToRegionShouldThrow()
        {
            var graph = new ControlFlowGraph <int>(IntArchitecture.Instance);
            var node  = new ControlFlowNode <int>(0);

            var region = new BasicControlFlowRegion <int>();

            graph.Regions.Add(region);

            Assert.Throws <ArgumentException>(() => region.Nodes.Add(node));
        }
Exemple #6
0
        public void AddNodeToRegionShouldSetParentRegion()
        {
            var graph = new ControlFlowGraph <int>(IntArchitecture.Instance);
            var node  = new ControlFlowNode <int>(0);

            graph.Nodes.Add(node);

            var region = new BasicControlFlowRegion <int>();

            graph.Regions.Add(region);

            region.Nodes.Add(node);

            Assert.Same(region, node.ParentRegion);
        }
Exemple #7
0
        public void RemoveNodeShouldSetRegionBackToParentGraph()
        {
            var graph = new ControlFlowGraph <int>(IntArchitecture.Instance);
            var node  = new ControlFlowNode <int>(0);

            graph.Nodes.Add(node);

            var region = new BasicControlFlowRegion <int>();

            graph.Regions.Add(region);

            region.Nodes.Add(node);
            region.Nodes.Remove(node);

            Assert.Same(graph, node.ParentRegion);
        }
Exemple #8
0
        public void RemoveNodeInRegionShouldRemoveFromRegion()
        {
            var graph = new ControlFlowGraph <int>(IntArchitecture.Instance);
            var node  = new ControlFlowNode <int>(0);

            graph.Nodes.Add(node);

            var region = new BasicControlFlowRegion <int>();

            graph.Regions.Add(region);
            region.Nodes.Add(node);

            graph.Nodes.Remove(node);

            Assert.Null(node.ParentRegion);
            Assert.DoesNotContain(node, region.Nodes);
        }
Exemple #9
0
        public void AddNodeFromAnotherRegionShouldThrow()
        {
            var graph = new ControlFlowGraph <int>(IntArchitecture.Instance);
            var node  = new ControlFlowNode <int>(0);

            graph.Nodes.Add(node);

            var region1 = new BasicControlFlowRegion <int>();
            var region2 = new BasicControlFlowRegion <int>();

            graph.Regions.Add(region1);
            graph.Regions.Add(region2);

            region1.Nodes.Add(node);

            Assert.Throws <ArgumentException>(() => region2.Nodes.Add(node));
        }
Exemple #10
0
        private ControlFlowRegion <Statement <TInstruction> > TransformRegion(IControlFlowRegion <TInstruction> region)
        {
            switch (region)
            {
            case BasicControlFlowRegion <TInstruction> basicRegion:
                // Create new basic region.
                var newBasicRegion = new BasicControlFlowRegion <Statement <TInstruction> >();
                TransformSubRegions(basicRegion, newBasicRegion);

                // Register basic region pair.
                _context.RegionsMapping[basicRegion] = newBasicRegion;

                return(newBasicRegion);

            case ExceptionHandlerRegion <TInstruction> ehRegion:
                var newEhRegion = new ExceptionHandlerRegion <Statement <TInstruction> >();

                // ProtectedRegion is read-only, so instead we just transform all sub regions and add it to the
                // existing protected region.
                TransformSubRegions(ehRegion.ProtectedRegion, newEhRegion.ProtectedRegion);
                _context.RegionsMapping[ehRegion.ProtectedRegion] = newEhRegion.ProtectedRegion;

                // Add handler regions.
                foreach (var subRegion in ehRegion.HandlerRegions)
                {
                    newEhRegion.HandlerRegions.Add(TransformRegion(subRegion));
                }

                return(newEhRegion);

            default:
                throw new ArgumentOutOfRangeException(nameof(region));
            }

            void TransformSubRegions(
                BasicControlFlowRegion <TInstruction> originalRegion,
                BasicControlFlowRegion <Statement <TInstruction> > newRegion)
            {
                foreach (var subRegion in originalRegion.Regions)
                {
                    newRegion.Regions.Add(TransformRegion(subRegion));
                }
            }
        }
Exemple #11
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));
        }