Loaders: Log extra NSO informations (#1661)

NSO files can contains useful informations who aren't currently logged.
This PR fix that by logging Module name, Libraries and SDK Version when they are available.
This commit is contained in:
Ac_K 2020-11-06 19:58:57 +01:00 committed by GitHub
parent 61e67b64ea
commit b677e44300
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -2,7 +2,11 @@ using LibHac.Common;
using LibHac.Fs; using LibHac.Fs;
using LibHac.FsSystem; using LibHac.FsSystem;
using LibHac.Loader; using LibHac.Loader;
using Ryujinx.Common.Logging;
using System; using System;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace Ryujinx.HLE.Loaders.Executables namespace Ryujinx.HLE.Loaders.Executables
{ {
@ -23,7 +27,7 @@ namespace Ryujinx.HLE.Loaders.Executables
public int DataSize { get; } public int DataSize { get; }
public int BssSize { get; } public int BssSize { get; }
public string Name; public string Name;
public Buffer32 BuildId; public Buffer32 BuildId;
public NsoExecutable(IStorage inStorage, string name = null) public NsoExecutable(IStorage inStorage, string name = null)
@ -33,22 +37,25 @@ namespace Ryujinx.HLE.Loaders.Executables
reader.Initialize(inStorage.AsFile(OpenMode.Read)).ThrowIfFailure(); reader.Initialize(inStorage.AsFile(OpenMode.Read)).ThrowIfFailure();
TextOffset = (int)reader.Header.Segments[0].MemoryOffset; TextOffset = (int)reader.Header.Segments[0].MemoryOffset;
RoOffset = (int)reader.Header.Segments[1].MemoryOffset; RoOffset = (int)reader.Header.Segments[1].MemoryOffset;
DataOffset = (int)reader.Header.Segments[2].MemoryOffset; DataOffset = (int)reader.Header.Segments[2].MemoryOffset;
BssSize = (int)reader.Header.BssSize; BssSize = (int)reader.Header.BssSize;
reader.GetSegmentSize(NsoReader.SegmentType.Data, out uint uncompressedSize).ThrowIfFailure(); reader.GetSegmentSize(NsoReader.SegmentType.Data, out uint uncompressedSize).ThrowIfFailure();
Program = new byte[DataOffset + uncompressedSize]; Program = new byte[DataOffset + uncompressedSize];
TextSize = DecompressSection(reader, NsoReader.SegmentType.Text, TextOffset, Program); TextSize = DecompressSection(reader, NsoReader.SegmentType.Text, TextOffset);
RoSize = DecompressSection(reader, NsoReader.SegmentType.Ro, RoOffset, Program); RoSize = DecompressSection(reader, NsoReader.SegmentType.Ro, RoOffset);
DataSize = DecompressSection(reader, NsoReader.SegmentType.Data, DataOffset, Program); DataSize = DecompressSection(reader, NsoReader.SegmentType.Data, DataOffset);
Name = name; Name = name;
BuildId = reader.Header.ModuleId; BuildId = reader.Header.ModuleId;
PrintRoSectionInfo();
} }
private static int DecompressSection(NsoReader reader, NsoReader.SegmentType segmentType, int offset, byte[] Program) private int DecompressSection(NsoReader reader, NsoReader.SegmentType segmentType, int offset)
{ {
reader.GetSegmentSize(segmentType, out uint uncompressedSize).ThrowIfFailure(); reader.GetSegmentSize(segmentType, out uint uncompressedSize).ThrowIfFailure();
@ -58,5 +65,40 @@ namespace Ryujinx.HLE.Loaders.Executables
return (int)uncompressedSize; return (int)uncompressedSize;
} }
private void PrintRoSectionInfo()
{
byte[] roBuffer = Ro.ToArray();
string rawTextBuffer = Encoding.ASCII.GetString(roBuffer, 0, RoSize);
StringBuilder stringBuilder = new StringBuilder();
int length = BitConverter.ToInt32(roBuffer, 4);
string moduleName = Encoding.UTF8.GetString(roBuffer, 8, length);
MatchCollection moduleMatches = Regex.Matches(rawTextBuffer, @"[a-z]:[\\/][ -~]{5,}\.nss", RegexOptions.IgnoreCase);
if (moduleMatches.Count > 0)
{
moduleName = moduleMatches.First().Value;
}
stringBuilder.AppendLine($" Module: {moduleName}");
MatchCollection fsSdkMatches = Regex.Matches(rawTextBuffer, @"sdk_version: ([0-9.]*)");
if (fsSdkMatches.Count != 0)
{
stringBuilder.AppendLine($" FS SDK Version: {fsSdkMatches.First().Value.Replace("sdk_version: ", "")}");
}
MatchCollection sdkMwMatches = Regex.Matches(rawTextBuffer, @"SDK MW[ -~]*");
if (sdkMwMatches.Count != 0)
{
string libHeader = " SDK Libraries: ";
string libContent = string.Join($"\n{new string(' ', libHeader.Length)}", sdkMwMatches);
stringBuilder.AppendLine($"{libHeader}{libContent}");
}
Logger.Info?.Print(LogClass.Loader, $"{Name}:\n{stringBuilder.ToString().TrimEnd('\r', '\n')}");
}
} }
} }