예제 #1
0
        private ATranslator GetTranslator()
        {
            if (Translator == null)
            {
                Translator = new ATranslator(SymbolTable);

                Translator.CpuTrace += CpuTraceHandler;
            }

            return(Translator);
        }
예제 #2
0
        public static ABlock DecodeBasicBlock(
            ATranslator Translator,
            AMemory Memory,
            long Start)
        {
            ABlock Block = new ABlock(Start);

            FillBlock(Memory, Block);

            return(Block);
        }
예제 #3
0
        public void Setup()
        {
            Position = 0x0;
            Size     = 0x1000;

            EntryPoint = Position;

            ATranslator Translator = new ATranslator();

            Memory = new AMemory();
            Memory.Manager.Map(Position, Size, 2, AMemoryPerm.Read | AMemoryPerm.Write | AMemoryPerm.Execute);
            Thread = new AThread(Translator, Memory, EntryPoint);
        }
예제 #4
0
        public void Setup()
        {
            Position = 0x0;
            Size     = 0x1000;

            EntryPoint = Position;

            ATranslator Translator = new ATranslator();

            RamPointer = Marshal.AllocHGlobal(new IntPtr(Size));
            Memory     = new AMemory(RamPointer);
            Memory.Map(Position, 0, Size);
            Thread = new AThread(Translator, Memory, EntryPoint);
        }
예제 #5
0
        public void Setup()
        {
            Position = 0x0;
            Size     = 0x1000;

            EntryPoint = Position;

            Ram = Marshal.AllocHGlobal((IntPtr)AMemoryMgr.RamSize);
            ATranslator Translator = new ATranslator();

            Allocator = new AMemoryAlloc();
            Memory    = new AMemory(Ram, Allocator);
            Memory.Manager.MapPhys(Position, Size, 2, AMemoryPerm.Read | AMemoryPerm.Write | AMemoryPerm.Execute);
            Thread = new AThread(Translator, Memory, ThreadPriority.Normal, EntryPoint);
        }
예제 #6
0
파일: Process.cs 프로젝트: asyrafc/Ryujinx
        private ATranslator GetTranslator()
        {
            if (Translator == null)
            {
                Dictionary <long, string> SymbolTable = new Dictionary <long, string>();

                foreach (Executable Exe in Executables)
                {
                    foreach (KeyValuePair <long, string> KV in Exe.SymbolTable)
                    {
                        SymbolTable.TryAdd(Exe.ImageBase + KV.Key, KV.Value);
                    }
                }

                Translator = new ATranslator(SymbolTable);

                Translator.CpuTrace += CpuTraceHandler;
            }

            return(Translator);
        }
예제 #7
0
        public void Setup()
        {
            Position = 0x1000;
            Size     = 0x1000;

            EntryPoint = Position;

            ATranslator Translator = new ATranslator();

            RamPointer = Marshal.AllocHGlobal(new IntPtr(Size));
            Memory     = new AMemory(RamPointer);
            Memory.Map(Position, 0, Size);
            Thread = new AThread(Translator, Memory, EntryPoint);

            if (UnicornAvailable)
            {
                UnicornEmu = new UnicornAArch64();
                UnicornEmu.MemoryMap((ulong)Position, (ulong)Size, MemoryPermission.READ | MemoryPermission.EXEC);
                UnicornEmu.PC = (ulong)EntryPoint;
            }
        }
예제 #8
0
        public AILEmitterCtx(ATranslator Translator, ABlock[] Graph, ABlock Root)
        {
            this.Translator = Translator;
            this.Graph      = Graph;
            this.Root       = Root;

            string SubName = $"Sub{Root.Position:X16}";

            Labels = new Dictionary <long, AILLabel>();

            Emitter = new AILEmitter(Graph, Root, SubName);

            ILBlock = Emitter.GetILBlock(0);

            OpcIndex = -1;

            if (!AdvanceOpCode())
            {
                throw new ArgumentException(nameof(Graph));
            }
        }
예제 #9
0
        public AILEmitterCtx(
            ATranslator Translator,
            ABlock[]    Graph,
            ABlock Root,
            string SubName)
        {
            if (Translator == null)
            {
                throw new ArgumentNullException(nameof(Translator));
            }

            if (Graph == null)
            {
                throw new ArgumentNullException(nameof(Graph));
            }

            if (Root == null)
            {
                throw new ArgumentNullException(nameof(Root));
            }

            this.Translator = Translator;
            this.Graph      = Graph;
            this.Root       = Root;

            Callees = new HashSet <long>();

            Labels = new Dictionary <long, AILLabel>();

            Emitter = new AILEmitter(Graph, Root, SubName);

            ILBlock = Emitter.GetILBlock(0);

            OpcIndex = -1;

            if (Graph.Length == 0 || !AdvanceOpCode())
            {
                throw new ArgumentException(nameof(Graph));
            }
        }
예제 #10
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);
        }