aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.HLE/HOS/Kernel/Process/HleProcessDebugger.cs
diff options
context:
space:
mode:
authorTSR Berry <20988865+TSRBerry@users.noreply.github.com>2023-04-08 01:22:00 +0200
committerMary <thog@protonmail.com>2023-04-27 23:51:14 +0200
commitcee712105850ac3385cd0091a923438167433f9f (patch)
tree4a5274b21d8b7f938c0d0ce18736d3f2993b11b1 /Ryujinx.HLE/HOS/Kernel/Process/HleProcessDebugger.cs
parentcd124bda587ef09668a971fa1cac1c3f0cfc9f21 (diff)
Move solution and projects to src
Diffstat (limited to 'Ryujinx.HLE/HOS/Kernel/Process/HleProcessDebugger.cs')
-rw-r--r--Ryujinx.HLE/HOS/Kernel/Process/HleProcessDebugger.cs465
1 files changed, 0 insertions, 465 deletions
diff --git a/Ryujinx.HLE/HOS/Kernel/Process/HleProcessDebugger.cs b/Ryujinx.HLE/HOS/Kernel/Process/HleProcessDebugger.cs
deleted file mode 100644
index 8fee5c0d..00000000
--- a/Ryujinx.HLE/HOS/Kernel/Process/HleProcessDebugger.cs
+++ /dev/null
@@ -1,465 +0,0 @@
-using Ryujinx.HLE.HOS.Diagnostics.Demangler;
-using Ryujinx.HLE.HOS.Kernel.Memory;
-using Ryujinx.HLE.HOS.Kernel.Threading;
-using Ryujinx.HLE.Loaders.Elf;
-using Ryujinx.Memory;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading;
-
-namespace Ryujinx.HLE.HOS.Kernel.Process
-{
- class HleProcessDebugger
- {
- private const int Mod0 = 'M' << 0 | 'O' << 8 | 'D' << 16 | '0' << 24;
-
- private KProcess _owner;
-
- private class Image
- {
- public ulong BaseAddress { get; }
- public ulong Size { get; }
- public ulong EndAddress => BaseAddress + Size;
-
- public ElfSymbol[] Symbols { get; }
-
- public Image(ulong baseAddress, ulong size, ElfSymbol[] symbols)
- {
- BaseAddress = baseAddress;
- Size = size;
- Symbols = symbols;
- }
- }
-
- private List<Image> _images;
-
- private int _loaded;
-
- public HleProcessDebugger(KProcess owner)
- {
- _owner = owner;
-
- _images = new List<Image>();
- }
-
- public string GetGuestStackTrace(KThread thread)
- {
- EnsureLoaded();
-
- var context = thread.Context;
-
- StringBuilder trace = new StringBuilder();
-
- trace.AppendLine($"Process: {_owner.Name}, PID: {_owner.Pid}");
-
- void AppendTrace(ulong address)
- {
- if (AnalyzePointer(out PointerInfo info, address, thread))
- {
- trace.AppendLine($" 0x{address:x16}\t{info.ImageDisplay}\t{info.SubDisplay}");
- }
- else
- {
- trace.AppendLine($" 0x{address:x16}");
- }
- }
-
- if (context.IsAarch32)
- {
- ulong framePointer = context.GetX(11);
-
- while (framePointer != 0)
- {
- if ((framePointer & 3) != 0 ||
- !_owner.CpuMemory.IsMapped(framePointer) ||
- !_owner.CpuMemory.IsMapped(framePointer + 4))
- {
- break;
- }
-
- AppendTrace(_owner.CpuMemory.Read<uint>(framePointer + 4));
-
- framePointer = _owner.CpuMemory.Read<uint>(framePointer);
- }
- }
- else
- {
- ulong framePointer = context.GetX(29);
-
- while (framePointer != 0)
- {
- if ((framePointer & 7) != 0 ||
- !_owner.CpuMemory.IsMapped(framePointer) ||
- !_owner.CpuMemory.IsMapped(framePointer + 8))
- {
- break;
- }
-
- AppendTrace(_owner.CpuMemory.Read<ulong>(framePointer + 8));
-
- framePointer = _owner.CpuMemory.Read<ulong>(framePointer);
- }
- }
-
- return trace.ToString();
- }
-
- public string GetCpuRegisterPrintout(KThread thread)
- {
- EnsureLoaded();
-
- var context = thread.Context;
-
- StringBuilder sb = new StringBuilder();
-
- string GetReg(int x)
- {
- var v = x == 32 ? context.Pc : context.GetX(x);
- if (!AnalyzePointer(out PointerInfo info, v, thread))
- {
- return $"0x{v:x16}";
- }
- else
- {
- if (!string.IsNullOrEmpty(info.ImageName))
- {
- return $"0x{v:x16} ({info.ImageDisplay})\t=> {info.SubDisplay}";
- }
- else
- {
- return $"0x{v:x16} ({info.SpDisplay})";
- }
- }
- }
-
- for (int i = 0; i <= 28; i++)
- {
- sb.AppendLine($"\tX[{i:d2}]:\t{GetReg(i)}");
- }
- sb.AppendLine($"\tFP:\t{GetReg(29)}");
- sb.AppendLine($"\tLR:\t{GetReg(30)}");
- sb.AppendLine($"\tSP:\t{GetReg(31)}");
- sb.AppendLine($"\tPC:\t{GetReg(32)}");
-
- return sb.ToString();
- }
-
- private bool TryGetSubName(Image image, ulong address, out ElfSymbol symbol)
- {
- address -= image.BaseAddress;
-
- int left = 0;
- int right = image.Symbols.Length - 1;
-
- while (left <= right)
- {
- int size = right - left;
-
- int middle = left + (size >> 1);
-
- symbol = image.Symbols[middle];
-
- ulong endAddr = symbol.Value + symbol.Size;
-
- if (address >= symbol.Value && address < endAddr)
- {
- return true;
- }
-
- if (address < symbol.Value)
- {
- right = middle - 1;
- }
- else
- {
- left = middle + 1;
- }
- }
-
- symbol = default;
-
- return false;
- }
-
- struct PointerInfo
- {
- public string ImageName;
- public string SubName;
-
- public ulong Offset;
- public ulong SubOffset;
-
- public string ImageDisplay => $"{ImageName}:0x{Offset:x4}";
- public string SubDisplay => SubOffset == 0 ? SubName : $"{SubName}:0x{SubOffset:x4}";
- public string SpDisplay => SubOffset == 0 ? "SP" : $"SP:-0x{SubOffset:x4}";
- }
-
- private bool AnalyzePointer(out PointerInfo info, ulong address, KThread thread)
- {
- if (AnalyzePointerFromImages(out info, address))
- {
- return true;
- }
-
- if (AnalyzePointerFromStack(out info, address, thread))
- {
- return true;
- }
-
- return false;
- }
-
- private bool AnalyzePointerFromImages(out PointerInfo info, ulong address)
- {
- info = default;
-
- Image image = GetImage(address, out int imageIndex);
-
- if (image == null)
- {
- // Value isn't a pointer to a known image...
- return false;
- }
-
- info.Offset = address - image.BaseAddress;
-
- // Try to find what this pointer is referring to
- if (TryGetSubName(image, address, out ElfSymbol symbol))
- {
- info.SubName = symbol.Name;
-
- // Demangle string if possible
- if (info.SubName.StartsWith("_Z"))
- {
- info.SubName = Demangler.Parse(info.SubName);
- }
- info.SubOffset = info.Offset - symbol.Value;
- }
- else
- {
- info.SubName = "";
- }
-
- info.ImageName = GetGuessedNsoNameFromIndex(imageIndex);
-
- return true;
- }
-
- private bool AnalyzePointerFromStack(out PointerInfo info, ulong address, KThread thread)
- {
- info = default;
-
- ulong sp = thread.Context.GetX(31);
- var memoryInfo = _owner.MemoryManager.QueryMemory(address);
- MemoryState memoryState = memoryInfo.State;
-
- if (!memoryState.HasFlag(MemoryState.Stack)) // Is this pointer within the stack?
- {
- return false;
- }
-
- info.SubOffset = address - sp;
-
- return true;
- }
-
- private Image GetImage(ulong address, out int index)
- {
- lock (_images)
- {
- for (index = _images.Count - 1; index >= 0; index--)
- {
- if (address >= _images[index].BaseAddress && address < _images[index].EndAddress)
- {
- return _images[index];
- }
- }
- }
-
- return null;
- }
-
- private string GetGuessedNsoNameFromIndex(int index)
- {
- if ((uint)index > 11)
- {
- return "???";
- }
-
- if (index == 0)
- {
- return "rtld";
- }
- else if (index == 1)
- {
- return "main";
- }
- else if (index == GetImagesCount() - 1)
- {
- return "sdk";
- }
- else
- {
- return "subsdk" + (index - 2);
- }
- }
-
- private int GetImagesCount()
- {
- lock (_images)
- {
- return _images.Count;
- }
- }
-
- private void EnsureLoaded()
- {
- if (Interlocked.CompareExchange(ref _loaded, 1, 0) == 0)
- {
- ScanMemoryForTextSegments();
- }
- }
-
- private void ScanMemoryForTextSegments()
- {
- ulong oldAddress = 0;
- ulong address = 0;
-
- while (address >= oldAddress)
- {
- KMemoryInfo info = _owner.MemoryManager.QueryMemory(address);
-
- if (info.State == MemoryState.Reserved)
- {
- break;
- }
-
- if (info.State == MemoryState.CodeStatic && info.Permission == KMemoryPermission.ReadAndExecute)
- {
- LoadMod0Symbols(_owner.CpuMemory, info.Address, info.Size);
- }
-
- oldAddress = address;
-
- address = info.Address + info.Size;
- }
- }
-
- private void LoadMod0Symbols(IVirtualMemoryManager memory, ulong textOffset, ulong textSize)
- {
- ulong mod0Offset = textOffset + memory.Read<uint>(textOffset + 4);
-
- if (mod0Offset < textOffset || !memory.IsMapped(mod0Offset) || (mod0Offset & 3) != 0)
- {
- return;
- }
-
- Dictionary<ElfDynamicTag, ulong> dynamic = new Dictionary<ElfDynamicTag, ulong>();
-
- int mod0Magic = memory.Read<int>(mod0Offset + 0x0);
-
- if (mod0Magic != Mod0)
- {
- return;
- }
-
- ulong dynamicOffset = memory.Read<uint>(mod0Offset + 0x4) + mod0Offset;
- ulong bssStartOffset = memory.Read<uint>(mod0Offset + 0x8) + mod0Offset;
- ulong bssEndOffset = memory.Read<uint>(mod0Offset + 0xc) + mod0Offset;
- ulong ehHdrStartOffset = memory.Read<uint>(mod0Offset + 0x10) + mod0Offset;
- ulong ehHdrEndOffset = memory.Read<uint>(mod0Offset + 0x14) + mod0Offset;
- ulong modObjOffset = memory.Read<uint>(mod0Offset + 0x18) + mod0Offset;
-
- bool isAArch32 = memory.Read<ulong>(dynamicOffset) > 0xFFFFFFFF || memory.Read<ulong>(dynamicOffset + 0x10) > 0xFFFFFFFF;
-
- while (true)
- {
- ulong tagVal;
- ulong value;
-
- if (isAArch32)
- {
- tagVal = memory.Read<uint>(dynamicOffset + 0);
- value = memory.Read<uint>(dynamicOffset + 4);
-
- dynamicOffset += 0x8;
- }
- else
- {
- tagVal = memory.Read<ulong>(dynamicOffset + 0);
- value = memory.Read<ulong>(dynamicOffset + 8);
-
- dynamicOffset += 0x10;
- }
-
- ElfDynamicTag tag = (ElfDynamicTag)tagVal;
-
- if (tag == ElfDynamicTag.DT_NULL)
- {
- break;
- }
-
- dynamic[tag] = value;
- }
-
- if (!dynamic.TryGetValue(ElfDynamicTag.DT_STRTAB, out ulong strTab) ||
- !dynamic.TryGetValue(ElfDynamicTag.DT_SYMTAB, out ulong symTab) ||
- !dynamic.TryGetValue(ElfDynamicTag.DT_SYMENT, out ulong symEntSize))
- {
- return;
- }
-
- ulong strTblAddr = textOffset + strTab;
- ulong symTblAddr = textOffset + symTab;
-
- List<ElfSymbol> symbols = new List<ElfSymbol>();
-
- while (symTblAddr < strTblAddr)
- {
- ElfSymbol sym = isAArch32 ? GetSymbol32(memory, symTblAddr, strTblAddr) : GetSymbol64(memory, symTblAddr, strTblAddr);
-
- symbols.Add(sym);
-
- symTblAddr += symEntSize;
- }
-
- lock (_images)
- {
- _images.Add(new Image(textOffset, textSize, symbols.OrderBy(x => x.Value).ToArray()));
- }
- }
-
- private ElfSymbol GetSymbol64(IVirtualMemoryManager memory, ulong address, ulong strTblAddr)
- {
- ElfSymbol64 sym = memory.Read<ElfSymbol64>(address);
-
- uint nameIndex = sym.NameOffset;
-
- string name = string.Empty;
-
- for (int chr; (chr = memory.Read<byte>(strTblAddr + nameIndex++)) != 0;)
- {
- name += (char)chr;
- }
-
- return new ElfSymbol(name, sym.Info, sym.Other, sym.SectionIndex, sym.ValueAddress, sym.Size);
- }
-
- private ElfSymbol GetSymbol32(IVirtualMemoryManager memory, ulong address, ulong strTblAddr)
- {
- ElfSymbol32 sym = memory.Read<ElfSymbol32>(address);
-
- uint nameIndex = sym.NameOffset;
-
- string name = string.Empty;
-
- for (int chr; (chr = memory.Read<byte>(strTblAddr + nameIndex++)) != 0;)
- {
- name += (char)chr;
- }
-
- return new ElfSymbol(name, sym.Info, sym.Other, sym.SectionIndex, sym.ValueAddress, sym.Size);
- }
- }
-}