Exemple #1
0
        public SubCode Parse(IList <IInstruction> instructions, uint taskStart, uint taskEnd)
        {
            var sindex       = getIndex(taskStart);
            var currentIndex = sindex;
            var subcode      = new SubCode();
            var endIndex     = getIndex(taskEnd);

            ParseRec(instructions, currentIndex, endIndex, subcode);
            return(subcode);
        }
Exemple #2
0
        public void Clone()
        {
            var s = new SubCode();

            foreach (var x in VisitedInstructions)
            {
                s.VisitedInstructions.Add(x);
            }
            foreach (var x in Branches)
            {
                s.Branches.Add(x);
            }
            foreach (var x in Returns)
            {
                s.Returns.Add(x);
            }
        }
Exemple #3
0
        private Tuple <Node <IList <IInstruction> >, IList <Node <IList <IInstruction> > > > Builder(SubCode code)
        {
            var returnNodes = new List <Node <IList <MIPSI.IInstruction> > >();
            var partitions  = new List <uint>();

            foreach (var x in code.Branches)
            {
                partitions.Add(x.Address);
                partitions.Add(x.Pointer - 1);
            }
            foreach (var x in code.FunctionCalls)
            {
                partitions.Add(x.CallerAddress);
                //partitions.Add(x.FunctionAddress);
            }
            foreach (var x in code.Jumps)
            {
                partitions.Add(x.From);
                partitions.Add(x.To);
            }
            var insts = code.VisitedInstructions.OrderBy(x => x.Key).ToDictionary(x => x.Key, y => y.Value);
            var nodes = new Dictionary <uint, Node <IList <IInstruction> > >();

            partitions = partitions.OrderBy(x => x).ToList();
            var currentNode      = CreateNode();
            var Root             = currentNode;
            var currentPartition = partitions.Count > 0 ? partitions[0] : uint.MaxValue;
            var partitionIndex   = 1;

            foreach (var x in insts)
            {
                currentNode.Content.Add(x.Value);
                nodes.Add(x.Key, currentNode);
                if (x.Key == currentPartition)
                {
                    var newnode = CreateNode();
                    currentNode.Left = newnode;
                    currentNode      = newnode;
                    currentPartition = partitionIndex < partitions.Count ? partitions[partitionIndex] : uint.MaxValue;
                    partitionIndex++;
                }
            }
            foreach (var x in code.Branches)
            {
                var from = nodes[x.Address];
                var to   = nodes[x.Pointer];
                //var notTaken = nodes[x.Address + 1];
                //from.Left = notTaken;
                from.Right = to;
            }
            foreach (var x in code.Jumps)
            {
                var from = nodes[x.From];
                var to   = nodes[x.To];
                from.Left = to;
            }
            foreach (var x in code.FunctionCalls)
            {
                var from        = nodes[x.CallerAddress];
                var returnPoint = nodes[x.CallerAddress + 1];
                var func        = Builder(x.FunctionBody);
                from.Left = func.Item1;
                foreach (var r in func.Item2)
                {
                    r.Left = returnPoint;
                }
            }
            foreach (var x in code.Returns)
            {
                returnNodes.Add(nodes[x]);
            }
            return(new Tuple <Node <IList <IInstruction> >, IList <Node <IList <IInstruction> > > >(Root, returnNodes));
        }
Exemple #4
0
        public Node <IList <MIPSI.IInstruction> > Build(SubCode code)
        {
            var Root = Builder(code).Item1;

            return(Root);
        }
Exemple #5
0
        private void ParseRec(IList <IInstruction> instructions, uint currentIndex, uint endIndex, SubCode subCode)
        {
            do
            {
                if (subCode.VisitedInstructions.ContainsKey(currentIndex))
                {
                    return;
                }

                var inst = instructions[(int)currentIndex];
                CheckInstruction(inst);
                subCode.AddVisitedInstruction(currentIndex, inst);


                if (inst is ITypeInstruction)
                {
                    var i = inst as ITypeInstruction;
                    switch (i.Opcode)
                    {
                    case Opcode.Branch:
                    case Opcode.BranchOnEqual:
                    case Opcode.BranchOnGreaterThanZero:
                    case Opcode.BranchOnLessThanOrEqualToZero:
                    case Opcode.BranchOnNotEqual:
                        var branchaddr = (uint)(currentIndex + (short)i.Immediate + 1);
                        subCode.Branches.Add(new Branch(currentIndex + 1, branchaddr, subCode.VisitedInstructions.ContainsKey(branchaddr)));
                        ParseRec(instructions, branchaddr, endIndex, subCode);

                        break;
                    }
                }
                else if (inst is RTypeInstruction)
                {
                    var r = inst as RTypeInstruction;
                    if (r.Function == RTypeFunction.JumpRegister && r.Rs == 31)
                    {
                        var nextIndex = currentIndex + 1;
                        var ist       = instructions[(int)(nextIndex)];
                        CheckInstruction(ist);
                        subCode.AddVisitedInstruction(nextIndex, ist);
                        subCode.Returns.Add(nextIndex);
                        return;
                    }
                }
                else if (inst is JTypeInstruction)
                {
                    var j = inst as JTypeInstruction;
                    if (j.JumpType == JumpType.JumpAndLink)
                    {
                        var fcnsubcode = new SubCode();
                        ParseRec(instructions, j.Target, endIndex, fcnsubcode);
                        subCode.FunctionCalls.Add(new FunctionCall()
                        {
                            CallerAddress = currentIndex + 1, FunctionBody = fcnsubcode, FunctionAddress = j.Target
                        });
                    }
                    else
                    {
                        var nextIndex = currentIndex + 1;
                        var ist       = instructions[(int)(nextIndex)];
                        CheckInstruction(ist);
                        subCode.AddVisitedInstruction(nextIndex, ist);
                        currentIndex = j.Target;
                        subCode.Jumps.Add(new Jump()
                        {
                            From = nextIndex, To = j.Target
                        });
                        continue;
                    }
                }

                currentIndex++;
            } while (currentIndex != endIndex + 1);
        }