KipExecutable.cs 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. using LibHac.Fs;
  2. using LibHac.Kernel;
  3. using System;
  4. namespace Ryujinx.HLE.Loaders.Executables
  5. {
  6. class KipExecutable : IExecutable
  7. {
  8. public byte[] Program { get; }
  9. public Span<byte> Text => Program.AsSpan().Slice((int)TextOffset, (int)TextSize);
  10. public Span<byte> Ro => Program.AsSpan().Slice((int)RoOffset, (int)RoSize);
  11. public Span<byte> Data => Program.AsSpan().Slice((int)DataOffset, (int)DataSize);
  12. public uint TextOffset { get; }
  13. public uint RoOffset { get; }
  14. public uint DataOffset { get; }
  15. public uint BssOffset { get; }
  16. public uint TextSize { get; }
  17. public uint RoSize { get; }
  18. public uint DataSize { get; }
  19. public uint BssSize { get; }
  20. public int[] Capabilities { get; }
  21. public bool UsesSecureMemory { get; }
  22. public bool Is64BitAddressSpace { get; }
  23. public bool Is64Bit { get; }
  24. public ulong ProgramId { get; }
  25. public byte Priority { get; }
  26. public int StackSize { get; }
  27. public byte IdealCoreId { get; }
  28. public int Version { get; }
  29. public string Name { get; }
  30. public KipExecutable(IStorage inStorage)
  31. {
  32. KipReader reader = new KipReader();
  33. reader.Initialize(inStorage).ThrowIfFailure();
  34. TextOffset = (uint)reader.Segments[0].MemoryOffset;
  35. RoOffset = (uint)reader.Segments[1].MemoryOffset;
  36. DataOffset = (uint)reader.Segments[2].MemoryOffset;
  37. BssOffset = (uint)reader.Segments[3].MemoryOffset;
  38. BssSize = (uint)reader.Segments[3].Size;
  39. StackSize = reader.StackSize;
  40. UsesSecureMemory = reader.UsesSecureMemory;
  41. Is64BitAddressSpace = reader.Is64BitAddressSpace;
  42. Is64Bit = reader.Is64Bit;
  43. ProgramId = reader.ProgramId;
  44. Priority = reader.Priority;
  45. IdealCoreId = reader.IdealCoreId;
  46. Version = reader.Version;
  47. Name = reader.Name.ToString();
  48. Capabilities = new int[32];
  49. for (int index = 0; index < Capabilities.Length; index++)
  50. {
  51. Capabilities[index] = (int)reader.Capabilities[index];
  52. }
  53. reader.GetSegmentSize(KipReader.SegmentType.Data, out int uncompressedSize).ThrowIfFailure();
  54. Program = new byte[DataOffset + uncompressedSize];
  55. TextSize = DecompressSection(reader, KipReader.SegmentType.Text, TextOffset, Program);
  56. RoSize = DecompressSection(reader, KipReader.SegmentType.Ro, RoOffset, Program);
  57. DataSize = DecompressSection(reader, KipReader.SegmentType.Data, DataOffset, Program);
  58. }
  59. private static uint DecompressSection(KipReader reader, KipReader.SegmentType segmentType, uint offset, byte[] program)
  60. {
  61. reader.GetSegmentSize(segmentType, out int uncompressedSize).ThrowIfFailure();
  62. var span = program.AsSpan().Slice((int)offset, uncompressedSize);
  63. reader.ReadSegment(segmentType, span).ThrowIfFailure();
  64. return (uint)uncompressedSize;
  65. }
  66. }
  67. }