aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThog <me@thog.eu>2020-01-12 12:06:26 +0100
committerGitHub <noreply@github.com>2020-01-12 12:06:26 +0100
commit9c8d48edff8e43318550a087816542391dffea83 (patch)
tree66423944888c0f5c299846877762f87c693386a9
parent78f6b1d3968a6c439cb36af74cae13c040c61af1 (diff)
Add 32 bits support to HleProcessDebugger (#859)
Co-authored-by: riperiperi <rhy3756547@hotmail.com>
-rw-r--r--Ryujinx.HLE/HOS/Kernel/Process/HleProcessDebugger.cs117
-rw-r--r--Ryujinx.HLE/Loaders/Elf/ElfSymbol.cs8
-rw-r--r--Ryujinx.HLE/Loaders/Elf/ElfSymbol32.cs12
-rw-r--r--Ryujinx.HLE/Loaders/Elf/ElfSymbol64.cs12
4 files changed, 114 insertions, 35 deletions
diff --git a/Ryujinx.HLE/HOS/Kernel/Process/HleProcessDebugger.cs b/Ryujinx.HLE/HOS/Kernel/Process/HleProcessDebugger.cs
index 4219eb75..75f52851 100644
--- a/Ryujinx.HLE/HOS/Kernel/Process/HleProcessDebugger.cs
+++ b/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);
+ }
}
}
} \ No newline at end of file
diff --git a/Ryujinx.HLE/Loaders/Elf/ElfSymbol.cs b/Ryujinx.HLE/Loaders/Elf/ElfSymbol.cs
index b655816f..9961afe1 100644
--- a/Ryujinx.HLE/Loaders/Elf/ElfSymbol.cs
+++ b/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);
diff --git a/Ryujinx.HLE/Loaders/Elf/ElfSymbol32.cs b/Ryujinx.HLE/Loaders/Elf/ElfSymbol32.cs
new file mode 100644
index 00000000..b7d98506
--- /dev/null
+++ b/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;
+ }
+}
diff --git a/Ryujinx.HLE/Loaders/Elf/ElfSymbol64.cs b/Ryujinx.HLE/Loaders/Elf/ElfSymbol64.cs
new file mode 100644
index 00000000..662de1ff
--- /dev/null
+++ b/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;
+ }
+}