Просмотр исходного кода

Fix compilation warnings and use new LibHac APIs for executable loading (#1350)

* Fix compilation warnings and use new LibHac APIs for executable loading

* Migrate NSO loader to the new reader and fix kip loader

* Fix CS0162 restore

* Remove extra return lines

* Address Moose's comment
Mary 5 лет назад
Родитель
Сommit
2c48750ff0

+ 0 - 3
Ryujinx.Graphics.Gpu/NvGpuFifo.cs

@@ -82,9 +82,6 @@ namespace Ryujinx.Graphics.Gpu
             }
         }
 
-        private int _currMacroPosition;
-        private int _currMacroBindIndex;
-
         private ShadowRamControl _shadowCtrl;
 
         private CachedMacro[] _macros;

+ 4 - 4
Ryujinx.HLE/HOS/ApplicationLoader.cs

@@ -415,13 +415,13 @@ namespace Ryujinx.HLE.HOS
 
             bool isNro = Path.GetExtension(filePath).ToLower() == ".nro";
 
-            IExecutable nro;
+            IExecutable executable;
 
             if (isNro)
             {
                 FileStream input = new FileStream(filePath, FileMode.Open);
                 NroExecutable obj = new NroExecutable(input);
-                nro = obj;
+                executable = obj;
 
                 // homebrew NRO can actually have some data after the actual NRO
                 if (input.Length > obj.FileSize)
@@ -493,7 +493,7 @@ namespace Ryujinx.HLE.HOS
             }
             else
             {
-                nro = new NsoExecutable(new LocalStorage(filePath, FileAccess.Read));
+                executable = new NsoExecutable(new LocalStorage(filePath, FileAccess.Read));
             }
 
             _contentManager.LoadEntries(_device);
@@ -502,7 +502,7 @@ namespace Ryujinx.HLE.HOS
             TitleId = metaData.Aci0.TitleId;
             TitleIs64Bit = metaData.Is64Bit;
 
-            ProgramLoader.LoadNsos(_device.System.KernelContext, metaData, executables: nro);
+            ProgramLoader.LoadNsos(_device.System.KernelContext, metaData, executables: executable);
         }
 
         private Npdm GetDefaultNpdm()

+ 9 - 9
Ryujinx.HLE/HOS/ProgramLoader.cs

@@ -32,7 +32,7 @@ namespace Ryujinx.HLE.HOS
 
             int codePagesCount = codeSize / KMemoryManager.PageSize;
 
-            ulong codeBaseAddress = (kip.Header.Flags & 0x10) != 0 ? 0x8000000UL : 0x200000UL;
+            ulong codeBaseAddress = kip.Is64BitAddressSpace ? 0x8000000UL : 0x200000UL;
 
             ulong codeAddress = codeBaseAddress + (ulong)kip.TextOffset;
 
@@ -45,27 +45,27 @@ namespace Ryujinx.HLE.HOS
                 mmuFlags |= 0x20;
             }
 
-            if ((kip.Header.Flags & 0x10) != 0)
+            if (kip.Is64BitAddressSpace)
             {
                 mmuFlags |= (int)AddressSpaceType.Addr39Bits << 1;
             }
 
-            if ((kip.Header.Flags & 0x08) != 0)
+            if (kip.Is64Bit)
             {
                 mmuFlags |= 1;
             }
 
             ProcessCreationInfo creationInfo = new ProcessCreationInfo(
-                kip.Header.Name,
-                kip.Header.ProcessCategory,
-                kip.Header.TitleId,
+                kip.Name,
+                kip.Version,
+                kip.ProgramId,
                 codeAddress,
                 codePagesCount,
                 mmuFlags,
                 0,
                 0);
 
-            MemoryRegion memoryRegion = (kip.Header.Flags & 0x20) != 0
+            MemoryRegion memoryRegion = kip.UsesSecureMemory
                 ? MemoryRegion.Service
                 : MemoryRegion.Application;
 
@@ -105,9 +105,9 @@ namespace Ryujinx.HLE.HOS
                 return false;
             }
 
-            process.DefaultCpuCore = kip.Header.DefaultCore;
+            process.DefaultCpuCore = kip.IdealCoreId;
 
-            result = process.Start(kip.Header.MainThreadPriority, (ulong)kip.Header.Sections[1].Attribute);
+            result = process.Start(kip.Priority, (ulong)kip.StackSize);
 
             if (result != KernelResult.Success)
             {

+ 2 - 2
Ryujinx.HLE/HOS/Services/Bluetooth/IBluetoothDriver.cs

@@ -9,9 +9,9 @@ namespace Ryujinx.HLE.HOS.Services.Bluetooth
     [Service("btdrv")]
     class IBluetoothDriver : IpcService
     {
-#pragma warning disable CS0169
+#pragma warning disable CS0414
         private string _unknownLowEnergy;
-#pragma warning restore CS0169
+#pragma warning restore CS0414
 
         public IBluetoothDriver(ServiceCtx context) { }
 

+ 2 - 0
Ryujinx.HLE/HOS/Services/Sockets/Nsd/Manager/FqdnResolver.cs

@@ -32,7 +32,9 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd.Manager
                     return ResultCode.Success;
                 }
 
+#pragma warning disable CS0162
                 return ResultCode.NullOutputObject;
+#pragma warning restore CS0162
             }
         }
 

+ 54 - 13
Ryujinx.HLE/Loaders/Executables/KipExecutable.cs

@@ -1,35 +1,76 @@
-using LibHac;
 using LibHac.Fs;
-using System.IO;
+using LibHac.Loader;
 
 namespace Ryujinx.HLE.Loaders.Executables
 {
-    class KipExecutable : Kip, IExecutable
+    class KipExecutable : IExecutable
     {
         public byte[] Text { get; }
         public byte[] Ro { get; }
         public byte[] Data { get; }
 
-        public int TextOffset => Header.Sections[0].OutOffset;
-        public int RoOffset => Header.Sections[1].OutOffset;
-        public int DataOffset => Header.Sections[2].OutOffset;
-        public int BssOffset => Header.Sections[3].OutOffset;
-        public int BssSize => Header.Sections[3].DecompressedSize;
+        public int TextOffset { get; }
+        public int RoOffset { get; }
+        public int DataOffset { get; }
+        public int BssOffset { get; }
+        public int BssSize { get; }
 
         public int[] Capabilities { get; }
+        public bool UsesSecureMemory { get; }
+        public bool Is64BitAddressSpace { get; }
+        public bool Is64Bit { get; }
+        public ulong ProgramId { get; }
+        public byte Priority { get; }
+        public int StackSize { get; }
+        public byte IdealCoreId { get; }
+        public int Version { get; }
+        public string Name { get; }
 
-        public KipExecutable(IStorage inStorage) : base(inStorage)
+        public KipExecutable(IStorage inStorage)
         {
+            KipReader reader = new KipReader();
+
+            reader.Initialize(inStorage).ThrowIfFailure();
+
+            TextOffset = reader.Segments[0].MemoryOffset;
+            RoOffset = reader.Segments[1].MemoryOffset;
+            DataOffset = reader.Segments[2].MemoryOffset;
+            BssOffset = reader.Segments[3].MemoryOffset;
+            BssSize = reader.Segments[3].Size;
+
+            StackSize = reader.StackSize;
+
+            UsesSecureMemory = reader.UsesSecureMemory;
+            Is64BitAddressSpace = reader.Is64BitAddressSpace;
+            Is64Bit = reader.Is64Bit;
+
+            ProgramId = reader.ProgramId;
+            Priority = reader.Priority;
+            IdealCoreId = reader.IdealCoreId;
+            Version = reader.Version;
+            Name = reader.Name.ToString();
+
             Capabilities = new int[32];
 
             for (int index = 0; index < Capabilities.Length; index++)
             {
-                Capabilities[index] = System.BitConverter.ToInt32(Header.Capabilities, index * 4);
+                Capabilities[index] = (int)reader.Capabilities[index];
             }
 
-            Text = DecompressSection(0);
-            Ro = DecompressSection(1);
-            Data = DecompressSection(2);
+            Text = DecompressSection(reader, KipReader.SegmentType.Text);
+            Ro = DecompressSection(reader, KipReader.SegmentType.Ro);
+            Data = DecompressSection(reader, KipReader.SegmentType.Data);
+        }
+
+        private static byte[] DecompressSection(KipReader reader, KipReader.SegmentType segmentType)
+        {
+            reader.GetSegmentSize(segmentType, out int uncompressedSize).ThrowIfFailure();
+
+            byte[] result = new byte[uncompressedSize];
+
+            reader.ReadSegment(segmentType, result).ThrowIfFailure();
+
+            return result;
         }
     }
 }

+ 31 - 12
Ryujinx.HLE/Loaders/Executables/NsoExecutable.cs

@@ -1,28 +1,47 @@
-using LibHac;
 using LibHac.Fs;
-using System;
-using System.IO;
+using LibHac.FsSystem;
+using LibHac.Loader;
 
 namespace Ryujinx.HLE.Loaders.Executables
 {
-    class NsoExecutable : Nso, IExecutable
+    class NsoExecutable : IExecutable
     {
         public byte[] Text { get; }
         public byte[] Ro { get; }
         public byte[] Data { get; }
 
-        public int TextOffset => (int)Sections[0].MemoryOffset;
-        public int RoOffset => (int)Sections[1].MemoryOffset;
-        public int DataOffset => (int)Sections[2].MemoryOffset;
+        public int TextOffset { get; }
+        public int RoOffset { get; }
+        public int DataOffset { get; }
         public int BssOffset => DataOffset + Data.Length;
 
-        public new int BssSize => (int)base.BssSize;
+        public int BssSize { get; }
 
-        public NsoExecutable(IStorage inStorage) : base(inStorage)
+        public NsoExecutable(IStorage inStorage)
         {
-            Text = Sections[0].DecompressSection();
-            Ro = Sections[1].DecompressSection();
-            Data =  Sections[2].DecompressSection();
+            NsoReader reader = new NsoReader();
+
+            reader.Initialize(inStorage.AsFile(OpenMode.Read)).ThrowIfFailure();
+
+            TextOffset = (int)reader.Header.Segments[0].MemoryOffset;
+            RoOffset = (int)reader.Header.Segments[1].MemoryOffset;
+            DataOffset = (int)reader.Header.Segments[2].MemoryOffset;
+            BssSize = (int)reader.Header.BssSize;
+
+            Text = DecompressSection(reader, NsoReader.SegmentType.Text);
+            Ro = DecompressSection(reader, NsoReader.SegmentType.Ro);
+            Data = DecompressSection(reader, NsoReader.SegmentType.Data);
+        }
+
+        private static byte[] DecompressSection(NsoReader reader, NsoReader.SegmentType segmentType)
+        {
+            reader.GetSegmentSize(segmentType, out uint uncompressedSize).ThrowIfFailure();
+
+            byte[] result = new byte[uncompressedSize];
+
+            reader.ReadSegment(segmentType, result).ThrowIfFailure();
+
+            return result;
         }
     }
 }