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