diff --git a/src/Ryujinx.HLE/Debugger/Debugger.cs b/src/Ryujinx.HLE/Debugger/Debugger.cs index 7a626b840..66e42681b 100644 --- a/src/Ryujinx.HLE/Debugger/Debugger.cs +++ b/src/Ryujinx.HLE/Debugger/Debugger.cs @@ -1105,7 +1105,7 @@ namespace Ryujinx.HLE.Debugger { var image = images[i]; ulong endAddress = image.BaseAddress + image.Size - 1; - string name = debugger.GetGuessedNsoNameFromIndex(i); + string name = image.Name; sb.AppendLine($" 0x{image.BaseAddress:x10} - 0x{endAddress:x10} {name}"); } } diff --git a/src/Ryujinx.HLE/HOS/Kernel/Process/HleProcessDebugger.cs b/src/Ryujinx.HLE/HOS/Kernel/Process/HleProcessDebugger.cs index 87da9f7a6..31360167f 100644 --- a/src/Ryujinx.HLE/HOS/Kernel/Process/HleProcessDebugger.cs +++ b/src/Ryujinx.HLE/HOS/Kernel/Process/HleProcessDebugger.cs @@ -20,6 +20,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process public class Image { + public string Name { get; internal set; } public ulong BaseAddress { get; } public ulong Size { get; } public ulong EndAddress => BaseAddress + Size; @@ -31,6 +32,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process BaseAddress = baseAddress; Size = size; Symbols = symbols; + Name = "(unknown)"; } } @@ -60,7 +62,9 @@ namespace Ryujinx.HLE.HOS.Kernel.Process if (!String.IsNullOrEmpty(ThreadName)) { trace.AppendLine($"Thread ID: {thread.ThreadUid} ({ThreadName})"); - } else { + } + else + { trace.AppendLine($"Thread ID: {thread.ThreadUid}"); } @@ -254,11 +258,66 @@ namespace Ryujinx.HLE.HOS.Kernel.Process info.SubName = string.Empty; } - info.ImageName = GetGuessedNsoNameFromIndex(imageIndex); + info.ImageName = image.Name; return true; } + private bool GetModuleName(out string moduleName, Image image) + { + moduleName = string.Empty; + + var rodataStart = image.BaseAddress + image.Size; + + KMemoryInfo roInfo = _owner.MemoryManager.QueryMemory(rodataStart); + if (roInfo.Permission != KMemoryPermission.Read) + { + return false; + } + + var rwdataStart = roInfo.Address + roInfo.Size; + + try + { + Span rodataBuf = stackalloc byte[0x208]; + _owner.CpuMemory.Read(rodataStart, rodataBuf); + + ulong deprecatedRwDataOffset = BitConverter.ToUInt64(rodataBuf); + // no name if using old format + if (image.BaseAddress + deprecatedRwDataOffset == rwdataStart) + { + return false; + } + + uint zero = BitConverter.ToUInt32(rodataBuf); + int pathLength = BitConverter.ToInt32(rodataBuf.Slice(4)); + if (zero != 0 || pathLength <= 0) + { + // try again with 12 byte offset, 20.0.0+ + _owner.CpuMemory.Read(rodataStart + 12, rodataBuf); + zero = BitConverter.ToUInt32(rodataBuf); + pathLength = BitConverter.ToInt32(rodataBuf.Slice(4)); + } + + if (zero != 0 || pathLength <= 0) + { + return false; + } + + pathLength = Math.Min(pathLength, rodataBuf.Length - 8); + var pathBuf = rodataBuf.Slice(8, pathLength); + int lastSlash = pathBuf.LastIndexOfAny(new byte[] { (byte)'\\', (byte)'/' }); + + moduleName = Encoding.ASCII.GetString(pathBuf.Slice(lastSlash + 1).TrimEnd((byte)0)); + + return true; + } + catch (InvalidMemoryRegionException) + { + return false; + } + } + private bool AnalyzePointerFromStack(out PointerInfo info, ulong address, KThread thread) { info = default; @@ -293,31 +352,6 @@ namespace Ryujinx.HLE.HOS.Kernel.Process return null; } - public 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) @@ -329,7 +363,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process public List GetLoadedImages() { EnsureLoaded(); - + lock (_images) { return [.. _images]; @@ -449,7 +483,17 @@ namespace Ryujinx.HLE.HOS.Kernel.Process lock (_images) { - _images.Add(new Image(textOffset, textSize, symbols.OrderBy(x => x.Value).ToArray())); + var image = new Image(textOffset, textSize, symbols.OrderBy(x => x.Value).ToArray()); + + string moduleName; + if (!GetModuleName(out moduleName, image)) + { + var newIndex = _images.Count; + moduleName = $"(unknown{newIndex})"; + } + image.Name = moduleName; + + _images.Add(image); } }