|
|
@@ -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);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|