Kaynağa Gözat

Add 32 bits support to HleProcessDebugger (#859)

Co-authored-by: riperiperi <rhy3756547@hotmail.com>
Thog 6 yıl önce
ebeveyn
işleme
9c8d48edff

+ 86 - 31
Ryujinx.HLE/HOS/Kernel/Process/HleProcessDebugger.cs

@@ -1,9 +1,12 @@
 using ARMeilleure.Memory;
+using Ryujinx.Common;
 using Ryujinx.HLE.HOS.Diagnostics.Demangler;
 using Ryujinx.HLE.HOS.Kernel.Memory;
 using Ryujinx.HLE.Loaders.Elf;
 using System.Collections.Generic;
+using System.IO;
 using System.Linq;
+using System.Runtime.CompilerServices;
 using System.Text;
 using System.Threading;
 
@@ -72,25 +75,43 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
                 }
             }
 
-            // TODO: ARM32.
-            long framePointer = (long)context.GetX(29);
-
             trace.AppendLine($"Process: {_owner.Name}, PID: {_owner.Pid}");
 
-            while (framePointer != 0)
+            if (context.IsAarch32)
             {
-                if ((framePointer & 7) != 0 ||
-                    !_owner.CpuMemory.IsMapped(framePointer) ||
-                    !_owner.CpuMemory.IsMapped(framePointer + 8))
+                long framePointer = (long)context.GetX(11);
+
+                while (framePointer != 0)
                 {
-                    break;
+                    if ((framePointer & 3) != 0 ||
+                        !_owner.CpuMemory.IsMapped(framePointer) ||
+                        !_owner.CpuMemory.IsMapped(framePointer + 4))
+                    {
+                        break;
+                    }
+
+                    AppendTrace(_owner.CpuMemory.ReadInt32(framePointer + 4));
+
+                    framePointer = _owner.CpuMemory.ReadInt32(framePointer);
                 }
+            }
+            else
+            {
+                long framePointer = (long)context.GetX(29);
 
-                // Note: This is the return address, we need to subtract one instruction
-                // worth of bytes to get the branch instruction address.
-                AppendTrace(_owner.CpuMemory.ReadInt64(framePointer + 8) - 4);
+                while (framePointer != 0)
+                {
+                    if ((framePointer & 7) != 0 ||
+                        !_owner.CpuMemory.IsMapped(framePointer) ||
+                        !_owner.CpuMemory.IsMapped(framePointer + 8))
+                    {
+                        break;
+                    }
 
-                framePointer = _owner.CpuMemory.ReadInt64(framePointer);
+                    AppendTrace(_owner.CpuMemory.ReadInt64(framePointer + 8));
+
+                    framePointer = _owner.CpuMemory.ReadInt64(framePointer);
+                }
             }
 
             return trace.ToString();
@@ -111,9 +132,9 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
 
                 ElfSymbol symbol = image.Symbols[middle];
 
-                long endAddr = symbol.Value + symbol.Size;
+                ulong endAddr = symbol.Value + symbol.Size;
 
-                if ((ulong)address >= (ulong)symbol.Value && (ulong)address < (ulong)endAddr)
+                if ((ulong)address >= symbol.Value && (ulong)address < endAddr)
                 {
                     name = symbol.Name;
 
@@ -242,13 +263,28 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
             long ehHdrEndOffset   = memory.ReadInt32(mod0Offset + 0x14) + mod0Offset;
             long modObjOffset     = memory.ReadInt32(mod0Offset + 0x18) + mod0Offset;
 
-            // TODO: Elf32.
+            bool isAArch32 = memory.ReadUInt64(dynamicOffset) > 0xFFFFFFFF || memory.ReadUInt64(dynamicOffset + 0x10) > 0xFFFFFFFF;
+
             while (true)
             {
-                long tagVal = memory.ReadInt64(dynamicOffset + 0);
-                long value  = memory.ReadInt64(dynamicOffset + 8);
+                long tagVal;
+                long value;
+
+                if (isAArch32)
+                {
+                    tagVal = memory.ReadInt32(dynamicOffset + 0);
+                    value  = memory.ReadInt32(dynamicOffset + 4);
+
+                    dynamicOffset += 0x8;
+                }
+                else
+                {
+                    tagVal = memory.ReadInt64(dynamicOffset + 0);
+                    value  = memory.ReadInt64(dynamicOffset + 8);
+
+                    dynamicOffset += 0x10;
+                }
 
-                dynamicOffset += 0x10;
 
                 ElfDynamicTag tag = (ElfDynamicTag)tagVal;
 
@@ -274,7 +310,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
 
             while ((ulong)symTblAddr < (ulong)strTblAddr)
             {
-                ElfSymbol sym = GetSymbol(memory, symTblAddr, strTblAddr);
+                ElfSymbol sym = isAArch32 ? GetSymbol32(memory, symTblAddr, strTblAddr) : GetSymbol64(memory, symTblAddr, strTblAddr);
 
                 symbols.Add(sym);
 
@@ -287,23 +323,42 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
             }
         }
 
-        private ElfSymbol GetSymbol(MemoryManager memory, long address, long strTblAddr)
+        private ElfSymbol GetSymbol64(MemoryManager memory, long address, long strTblAddr)
         {
-            int  nameIndex = memory.ReadInt32(address + 0);
-            int  info      = memory.ReadByte (address + 4);
-            int  other     = memory.ReadByte (address + 5);
-            int  shIdx     = memory.ReadInt16(address + 6);
-            long value     = memory.ReadInt64(address + 8);
-            long size      = memory.ReadInt64(address + 16);
+            using (BinaryReader inputStream = new BinaryReader(new MemoryStream(memory.ReadBytes(address, Unsafe.SizeOf<ElfSymbol64>()))))
+            {
+                ElfSymbol64 sym = inputStream.ReadStruct<ElfSymbol64>();
 
-            string name = string.Empty;
+                uint nameIndex = sym.NameOffset;
 
-            for (int chr; (chr = memory.ReadByte(strTblAddr + nameIndex++)) != 0;)
-            {
-                name += (char)chr;
+                string name = string.Empty;
+
+                for (int chr; (chr = memory.ReadByte(strTblAddr + nameIndex++)) != 0;)
+                {
+                    name += (char)chr;
+                }
+
+                return new ElfSymbol(name, sym.Info, sym.Other, sym.SectionIndex, sym.ValueAddress, sym.Size);
             }
+        }
+
+        private ElfSymbol GetSymbol32(MemoryManager memory, long address, long strTblAddr)
+        {
+            using (BinaryReader inputStream = new BinaryReader(new MemoryStream(memory.ReadBytes(address, Unsafe.SizeOf<ElfSymbol32>()))))
+            {
+                ElfSymbol32 sym = inputStream.ReadStruct<ElfSymbol32>();
+
+                uint nameIndex = sym.NameOffset;
 
-            return new ElfSymbol(name, info, other, shIdx, value, size);
+                string name = string.Empty;
+
+                for (int chr; (chr = memory.ReadByte(strTblAddr + nameIndex++)) != 0;)
+                {
+                    name += (char)chr;
+                }
+
+                return new ElfSymbol(name, sym.Info, sym.Other, sym.SectionIndex, sym.ValueAddress, sym.Size);
+            }
         }
     }
 }

+ 4 - 4
Ryujinx.HLE/Loaders/Elf/ElfSymbol.cs

@@ -17,16 +17,16 @@ namespace Ryujinx.HLE.Loaders.Elf
             Binding == ElfSymbolBinding.StbWeak;
 
         public int  ShIdx { get; private set; }
-        public long Value { get; private set; }
-        public long Size  { get; private set; }
+        public ulong Value { get; private set; }
+        public ulong Size  { get; private set; }
 
         public ElfSymbol(
             string name,
             int    info,
             int    other,
             int    shIdx,
-            long   value,
-            long   size)
+            ulong  value,
+            ulong  size)
         {
             Name       = name;
             Type       = (ElfSymbolType)(info & 0xf);

+ 12 - 0
Ryujinx.HLE/Loaders/Elf/ElfSymbol32.cs

@@ -0,0 +1,12 @@
+namespace Ryujinx.HLE.Loaders.Elf
+{
+    struct ElfSymbol32
+    {
+        public uint   NameOffset;
+        public uint   ValueAddress;
+        public uint   Size;
+        public char   Info;
+        public char   Other;
+        public ushort SectionIndex;
+    }
+}

+ 12 - 0
Ryujinx.HLE/Loaders/Elf/ElfSymbol64.cs

@@ -0,0 +1,12 @@
+namespace Ryujinx.HLE.Loaders.Elf
+{
+    struct ElfSymbol64
+    {
+        public uint   NameOffset;
+        public char   Info;
+        public char   Other;
+        public ushort SectionIndex;
+        public ulong  ValueAddress;
+        public ulong  Size;
+    }
+}