diff options
author | TSR Berry <20988865+TSRBerry@users.noreply.github.com> | 2023-04-08 01:22:00 +0200 |
---|---|---|
committer | Mary <thog@protonmail.com> | 2023-04-27 23:51:14 +0200 |
commit | cee712105850ac3385cd0091a923438167433f9f (patch) | |
tree | 4a5274b21d8b7f938c0d0ce18736d3f2993b11b1 /Ryujinx.HLE/HOS/Kernel/Process/HleProcessDebugger.cs | |
parent | cd124bda587ef09668a971fa1cac1c3f0cfc9f21 (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.cs | 465 |
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); - } - } -} |