NsoExecutable.cs 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. using LibHac.Fs;
  2. using LibHac.FsSystem;
  3. using LibHac.Loader;
  4. namespace Ryujinx.HLE.Loaders.Executables
  5. {
  6. class NsoExecutable : IExecutable
  7. {
  8. public byte[] Text { get; }
  9. public byte[] Ro { get; }
  10. public byte[] Data { get; }
  11. public int TextOffset { get; }
  12. public int RoOffset { get; }
  13. public int DataOffset { get; }
  14. public int BssOffset => DataOffset + Data.Length;
  15. public int BssSize { get; }
  16. public NsoExecutable(IStorage inStorage)
  17. {
  18. NsoReader reader = new NsoReader();
  19. reader.Initialize(inStorage.AsFile(OpenMode.Read)).ThrowIfFailure();
  20. TextOffset = (int)reader.Header.Segments[0].MemoryOffset;
  21. RoOffset = (int)reader.Header.Segments[1].MemoryOffset;
  22. DataOffset = (int)reader.Header.Segments[2].MemoryOffset;
  23. BssSize = (int)reader.Header.BssSize;
  24. Text = DecompressSection(reader, NsoReader.SegmentType.Text);
  25. Ro = DecompressSection(reader, NsoReader.SegmentType.Ro);
  26. Data = DecompressSection(reader, NsoReader.SegmentType.Data);
  27. }
  28. private static byte[] DecompressSection(NsoReader reader, NsoReader.SegmentType segmentType)
  29. {
  30. reader.GetSegmentSize(segmentType, out uint uncompressedSize).ThrowIfFailure();
  31. byte[] result = new byte[uncompressedSize];
  32. reader.ReadSegment(segmentType, result).ThrowIfFailure();
  33. return result;
  34. }
  35. }
  36. }