Beispiel #1
0
        public static AOpCode DecodeOpCode(AThreadState State, AMemory Memory, long Position)
        {
            int OpCode = Memory.ReadInt32(Position);

            AInst Inst;

            if (State.ExecutionMode == AExecutionMode.AArch64)
            {
                Inst = AOpCodeTable.GetInstA64(OpCode);
            }
            else
            {
                //TODO: Thumb support.
                Inst = AOpCodeTable.GetInstA32(OpCode);
            }

            AOpCode DecodedOpCode = new AOpCode(AInst.Undefined, Position, OpCode);

            if (Inst.Type != null)
            {
                DecodedOpCode = MakeOpCode(Inst.Type, Inst, Position, OpCode);
            }

            return(DecodedOpCode);
        }
Beispiel #2
0
        public static AOpCode DecodeOpCode(AMemory Memory, long Position)
        {
            int OpCode = Memory.ReadInt32(Position);

            AInst Inst = AOpCodeTable.GetInst(OpCode);

            AOpCode DecodedOpCode = new AOpCode(AInst.Undefined, Position, OpCode);

            if (Inst.Type != null)
            {
                DecodedOpCode = CreateOpCode(Inst.Type, Inst, Position, OpCode);
            }

            return(DecodedOpCode);
        }
Beispiel #3
0
 private static bool IsException(AOpCode OpCode)
 {
     return(OpCode.Emitter == AInstEmit.Brk ||
            OpCode.Emitter == AInstEmit.Svc ||
            OpCode.Emitter == AInstEmit.Und);
 }
Beispiel #4
0
 private static bool IsBranch(AOpCode OpCode)
 {
     return(OpCode is AOpCodeBImm ||
            OpCode is AOpCodeBReg);
 }
Beispiel #5
0
        public static (ABlock[] Graph, ABlock Root) DecodeSubroutine(ATranslator Translator, long Start)
        {
            Dictionary <long, ABlock> Visited    = new Dictionary <long, ABlock>();
            Dictionary <long, ABlock> VisitedEnd = new Dictionary <long, ABlock>();

            Queue <ABlock> Blocks = new Queue <ABlock>();

            ABlock Enqueue(long Position)
            {
                if (!Visited.TryGetValue(Position, out ABlock Output))
                {
                    Output = new ABlock(Position);

                    Blocks.Enqueue(Output);

                    Visited.Add(Position, Output);
                }

                return(Output);
            }

            ABlock Root = Enqueue(Start);

            while (Blocks.Count > 0)
            {
                ABlock Current = Blocks.Dequeue();

                FillBlock(Translator.Thread.Memory, Current);

                //Set child blocks. "Branch" is the block the branch instruction
                //points to (when taken), "Next" is the block at the next address,
                //executed when the branch is not taken. For Unconditional Branches
                //(except BL/BLR that are sub calls) or end of executable, Next is null.
                if (Current.OpCodes.Count > 0)
                {
                    bool HasCachedSub = false;

                    AOpCode LastOp = Current.GetLastOp();

                    if (LastOp is AOpCodeBImm Op)
                    {
                        if (Op.Emitter == AInstEmit.Bl)
                        {
                            HasCachedSub = Translator.HasCachedSub(Op.Imm);
                        }
                        else
                        {
                            Current.Branch = Enqueue(Op.Imm);
                        }
                    }

                    if ((!(LastOp is AOpCodeBImmAl) &&
                         !(LastOp is AOpCodeBReg)) || HasCachedSub)
                    {
                        Current.Next = Enqueue(Current.EndPosition);
                    }
                }

                //If we have on the tree two blocks with the same end position,
                //then we need to split the bigger block and have two small blocks,
                //the end position of the bigger "Current" block should then be == to
                //the position of the "Smaller" block.
                while (VisitedEnd.TryGetValue(Current.EndPosition, out ABlock Smaller))
                {
                    if (Current.Position > Smaller.Position)
                    {
                        ABlock Temp = Smaller;

                        Smaller = Current;
                        Current = Temp;
                    }

                    Current.EndPosition = Smaller.Position;
                    Current.Next        = Smaller;
                    Current.Branch      = null;

                    Current.OpCodes.RemoveRange(
                        Current.OpCodes.Count - Smaller.OpCodes.Count,
                        Smaller.OpCodes.Count);

                    VisitedEnd[Smaller.EndPosition] = Smaller;
                }

                VisitedEnd.Add(Current.EndPosition, Current);
            }

            //Make and sort Graph blocks array by position.
            ABlock[] Graph = new ABlock[Visited.Count];

            while (Visited.Count > 0)
            {
                ulong FirstPos = ulong.MaxValue;

                foreach (ABlock Block in Visited.Values)
                {
                    if (FirstPos > (ulong)Block.Position)
                    {
                        FirstPos = (ulong)Block.Position;
                    }
                }

                ABlock Current = Visited[(long)FirstPos];

                do
                {
                    Graph[Graph.Length - Visited.Count] = Current;

                    Visited.Remove(Current.Position);

                    Current = Current.Next;
                }while (Current != null);
            }

            return(Graph, Root);
        }