Sfoglia il codice sorgente

Correct type of executable sizes (#1802)

gdkchan 5 anni fa
parent
commit
19d18662ea

+ 10 - 0
Ryujinx.Common/Utilities/BitUtils.cs

@@ -4,6 +4,11 @@ namespace Ryujinx.Common
     {
         private static readonly byte[] ClzNibbleTbl = { 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 };
 
+        public static uint AlignUp(uint value, int size)
+        {
+            return (uint)AlignUp((int)value, size);
+        }
+
         public static int AlignUp(int value, int size)
         {
             return (value + (size - 1)) & -size;
@@ -19,6 +24,11 @@ namespace Ryujinx.Common
             return (value + (size - 1)) & -(long)size;
         }
 
+        public static uint AlignDown(uint value, int size)
+        {
+            return (uint)AlignDown((int)value, size);
+        }
+
         public static int AlignDown(int value, int size)
         {
             return value & -size;

+ 1 - 1
Ryujinx.HLE/HOS/Kernel/Process/KProcess.cs

@@ -1072,7 +1072,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
 
         private bool InvalidAccessHandler(ulong va)
         {
-            KernelStatic.GetCurrentThread().PrintGuestStackTrace();
+            KernelStatic.GetCurrentThread()?.PrintGuestStackTrace();
 
             Logger.Error?.Print(LogClass.Cpu, $"Invalid memory access at virtual address 0x{va:X16}.");
 

+ 17 - 21
Ryujinx.HLE/HOS/ProgramLoader.cs

@@ -21,16 +21,16 @@ namespace Ryujinx.HLE.HOS
 
         public static bool LoadKip(KernelContext context, KipExecutable kip)
         {
-            int endOffset = kip.DataOffset + kip.Data.Length;
+            uint endOffset = kip.DataOffset + (uint)kip.Data.Length;
 
             if (kip.BssSize != 0)
             {
                 endOffset = kip.BssOffset + kip.BssSize;
             }
 
-            int codeSize = BitUtils.AlignUp(kip.TextOffset + endOffset, KMemoryManager.PageSize);
+            uint codeSize = BitUtils.AlignUp(kip.TextOffset + endOffset, KMemoryManager.PageSize);
 
-            int codePagesCount = codeSize / KMemoryManager.PageSize;
+            int codePagesCount = (int)(codeSize / KMemoryManager.PageSize);
 
             ulong codeBaseAddress = kip.Is64BitAddressSpace ? 0x8000000UL : 0x200000UL;
 
@@ -124,35 +124,31 @@ namespace Ryujinx.HLE.HOS
             return true;
         }
 
-        public static bool LoadNsos(
-                   KernelContext context,
-                   Npdm          metaData,
-                   byte[]        arguments = null,
-            params IExecutable[] executables)
+        public static bool LoadNsos(KernelContext context, Npdm metaData, byte[] arguments = null, params IExecutable[] executables)
         {
             ulong argsStart = 0;
-            int   argsSize  = 0;
+            uint  argsSize  = 0;
             ulong codeStart = metaData.Is64Bit ? 0x8000000UL : 0x200000UL;
-            int   codeSize  = 0;
+            uint  codeSize  = 0;
 
             ulong[] nsoBase = new ulong[executables.Length];
 
             for (int index = 0; index < executables.Length; index++)
             {
-                IExecutable staticObject = executables[index];
+                IExecutable nso = executables[index];
 
-                int textEnd = staticObject.TextOffset + staticObject.Text.Length;
-                int roEnd   = staticObject.RoOffset   + staticObject.Ro.Length;
-                int dataEnd = staticObject.DataOffset + staticObject.Data.Length + staticObject.BssSize;
+                uint textEnd = nso.TextOffset + (uint)nso.Text.Length;
+                uint roEnd   = nso.RoOffset   + (uint)nso.Ro.Length;
+                uint dataEnd = nso.DataOffset + (uint)nso.Data.Length + nso.BssSize;
 
-                int nsoSize = textEnd;
+                uint nsoSize = textEnd;
 
-                if ((uint)nsoSize < (uint)roEnd)
+                if (nsoSize < roEnd)
                 {
                     nsoSize = roEnd;
                 }
 
-                if ((uint)nsoSize < (uint)dataEnd)
+                if (nsoSize < dataEnd)
                 {
                     nsoSize = dataEnd;
                 }
@@ -167,16 +163,16 @@ namespace Ryujinx.HLE.HOS
                 {
                     argsStart = (ulong)codeSize;
 
-                    argsSize = BitUtils.AlignDown(arguments.Length * 2 + ArgsTotalSize - 1, KMemoryManager.PageSize);
+                    argsSize = (uint)BitUtils.AlignDown(arguments.Length * 2 + ArgsTotalSize - 1, KMemoryManager.PageSize);
 
                     codeSize += argsSize;
                 }
             }
 
             PtcProfiler.StaticCodeStart = codeStart;
-            PtcProfiler.StaticCodeSize  = codeSize;
+            PtcProfiler.StaticCodeSize  = (int)codeSize;
 
-            int codePagesCount = codeSize / KMemoryManager.PageSize;
+            int codePagesCount = (int)(codeSize / KMemoryManager.PageSize);
 
             int personalMmHeapPagesCount = metaData.PersonalMmHeapSize / KMemoryManager.PageSize;
 
@@ -284,7 +280,7 @@ namespace Ryujinx.HLE.HOS
             process.CpuMemory.Write(roStart,   image.Ro);
             process.CpuMemory.Write(dataStart, image.Data);
 
-            MemoryHelper.FillWithZeros(process.CpuMemory, (long)bssStart, image.BssSize);
+            process.CpuMemory.Fill(bssStart, image.BssSize, 0);
 
             KernelResult SetProcessMemoryPermission(ulong address, ulong size, KMemoryPermission permission)
             {

+ 1 - 1
Ryujinx.HLE/HOS/Services/Ro/IRoInterface.cs

@@ -187,7 +187,7 @@ namespace Ryujinx.HLE.HOS.Services.Ro
                 return ResultCode.InvalidNro;
             }
 
-            int totalSize = nro.Text.Length + nro.Ro.Length + nro.Data.Length + nro.BssSize;
+            uint totalSize = (uint)nro.Text.Length + (uint)nro.Ro.Length + (uint)nro.Data.Length + nro.BssSize;
 
             // Apply patches
             context.Device.FileSystem.ModLoader.ApplyNroPatches(nro);

+ 6 - 6
Ryujinx.HLE/Loaders/Executables/IExecutable.cs

@@ -4,15 +4,15 @@ namespace Ryujinx.HLE.Loaders.Executables
 {
     interface IExecutable
     {
-        byte[] Program { get; }        
+        byte[] Program { get; }
         Span<byte> Text { get; }
         Span<byte> Ro   { get; }
         Span<byte> Data { get; }
 
-        int TextOffset { get; }
-        int RoOffset   { get; }
-        int DataOffset { get; }
-        int BssOffset  { get; }
-        int BssSize    { get; }
+        uint TextOffset { get; }
+        uint RoOffset   { get; }
+        uint DataOffset { get; }
+        uint BssOffset  { get; }
+        uint BssSize    { get; }
     }
 }

+ 19 - 19
Ryujinx.HLE/Loaders/Executables/KipExecutable.cs

@@ -7,19 +7,19 @@ namespace Ryujinx.HLE.Loaders.Executables
     class KipExecutable : IExecutable
     {
         public byte[] Program { get; }
-        public Span<byte> Text => Program.AsSpan().Slice(TextOffset, TextSize);
-        public Span<byte> Ro   => Program.AsSpan().Slice(RoOffset,   RoSize);
-        public Span<byte> Data => Program.AsSpan().Slice(DataOffset, DataSize);
+        public Span<byte> Text => Program.AsSpan().Slice((int)TextOffset, (int)TextSize);
+        public Span<byte> Ro   => Program.AsSpan().Slice((int)RoOffset,   (int)RoSize);
+        public Span<byte> Data => Program.AsSpan().Slice((int)DataOffset, (int)DataSize);
 
-        public int TextOffset { get; }
-        public int RoOffset { get; }
-        public int DataOffset { get; }
-        public int BssOffset { get; }
+        public uint TextOffset { get; }
+        public uint RoOffset { get; }
+        public uint DataOffset { get; }
+        public uint BssOffset { get; }
 
-        public int TextSize { get; }
-        public int RoSize { get; }
-        public int DataSize { get; }
-        public int BssSize { get; }
+        public uint TextSize { get; }
+        public uint RoSize { get; }
+        public uint DataSize { get; }
+        public uint BssSize { get; }
 
         public int[] Capabilities { get; }
         public bool UsesSecureMemory { get; }
@@ -38,11 +38,11 @@ namespace Ryujinx.HLE.Loaders.Executables
 
             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;
+            TextOffset = (uint)reader.Segments[0].MemoryOffset;
+            RoOffset = (uint)reader.Segments[1].MemoryOffset;
+            DataOffset = (uint)reader.Segments[2].MemoryOffset;
+            BssOffset = (uint)reader.Segments[3].MemoryOffset;
+            BssSize = (uint)reader.Segments[3].Size;
 
             StackSize = reader.StackSize;
 
@@ -71,15 +71,15 @@ namespace Ryujinx.HLE.Loaders.Executables
             DataSize = DecompressSection(reader, KipReader.SegmentType.Data, DataOffset, Program);
         }
 
-        private static int DecompressSection(KipReader reader, KipReader.SegmentType segmentType, int offset, byte[] program)
+        private static uint DecompressSection(KipReader reader, KipReader.SegmentType segmentType, uint offset, byte[] program)
         {
             reader.GetSegmentSize(segmentType, out int uncompressedSize).ThrowIfFailure();
 
-            var span = program.AsSpan().Slice(offset, uncompressedSize);
+            var span = program.AsSpan().Slice((int)offset, uncompressedSize);
 
             reader.ReadSegment(segmentType, span).ThrowIfFailure();
 
-            return uncompressedSize;
+            return (uint)uncompressedSize;
         }
     }
 }

+ 10 - 10
Ryujinx.HLE/Loaders/Executables/NroExecutable.cs

@@ -7,18 +7,18 @@ namespace Ryujinx.HLE.Loaders.Executables
     class NroExecutable : Nro, IExecutable
     {
         public byte[] Program { get; }
-        public Span<byte> Text => Program.AsSpan().Slice(TextOffset, (int)Header.NroSegments[0].Size);
-        public Span<byte> Ro   => Program.AsSpan().Slice(RoOffset,   (int)Header.NroSegments[1].Size);
-        public Span<byte> Data => Program.AsSpan().Slice(DataOffset, (int)Header.NroSegments[2].Size);
+        public Span<byte> Text => Program.AsSpan().Slice((int)TextOffset, (int)Header.NroSegments[0].Size);
+        public Span<byte> Ro   => Program.AsSpan().Slice((int)RoOffset,   (int)Header.NroSegments[1].Size);
+        public Span<byte> Data => Program.AsSpan().Slice((int)DataOffset, (int)Header.NroSegments[2].Size);
 
-        public int TextOffset => (int)Header.NroSegments[0].FileOffset;
-        public int RoOffset   => (int)Header.NroSegments[1].FileOffset;
-        public int DataOffset => (int)Header.NroSegments[2].FileOffset;
-        public int BssOffset  => DataOffset + Data.Length;     
-        public int BssSize    => (int)Header.BssSize;
+        public uint TextOffset => Header.NroSegments[0].FileOffset;
+        public uint RoOffset   => Header.NroSegments[1].FileOffset;
+        public uint DataOffset => Header.NroSegments[2].FileOffset;
+        public uint BssOffset  => DataOffset + (uint)Data.Length;
+        public uint BssSize    => Header.BssSize;
 
-        public int Mod0Offset => Start.Mod0Offset;
-        public int FileSize   => (int)Header.Size;
+        public uint Mod0Offset => (uint)Start.Mod0Offset;
+        public uint FileSize   => Header.Size;
 
         public ulong SourceAddress { get; private set; }
         public ulong BssAddress    { get; private set; }

+ 19 - 19
Ryujinx.HLE/Loaders/Executables/NsoExecutable.cs

@@ -13,19 +13,19 @@ namespace Ryujinx.HLE.Loaders.Executables
     class NsoExecutable : IExecutable
     {
         public byte[] Program { get; }
-        public Span<byte> Text => Program.AsSpan().Slice(TextOffset, TextSize);
-        public Span<byte> Ro   => Program.AsSpan().Slice(RoOffset,   RoSize);
-        public Span<byte> Data => Program.AsSpan().Slice(DataOffset, DataSize);
+        public Span<byte> Text => Program.AsSpan().Slice((int)TextOffset, (int)TextSize);
+        public Span<byte> Ro   => Program.AsSpan().Slice((int)RoOffset,   (int)RoSize);
+        public Span<byte> Data => Program.AsSpan().Slice((int)DataOffset, (int)DataSize);
 
-        public int TextOffset { get; }
-        public int RoOffset { get; }
-        public int DataOffset { get; }
-        public int BssOffset => DataOffset + Data.Length;
+        public uint TextOffset { get; }
+        public uint RoOffset { get; }
+        public uint DataOffset { get; }
+        public uint BssOffset => DataOffset + (uint)Data.Length;
 
-        public int TextSize { get; }
-        public int RoSize { get; }
-        public int DataSize { get; }
-        public int BssSize { get; }
+        public uint TextSize { get; }
+        public uint RoSize { get; }
+        public uint DataSize { get; }
+        public uint BssSize { get; }
 
         public string   Name;
         public Buffer32 BuildId;
@@ -36,10 +36,10 @@ namespace Ryujinx.HLE.Loaders.Executables
 
             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;
+            TextOffset = reader.Header.Segments[0].MemoryOffset;
+            RoOffset   = reader.Header.Segments[1].MemoryOffset;
+            DataOffset = reader.Header.Segments[2].MemoryOffset;
+            BssSize    = reader.Header.BssSize;
 
             reader.GetSegmentSize(NsoReader.SegmentType.Data, out uint uncompressedSize).ThrowIfFailure();
 
@@ -55,21 +55,21 @@ namespace Ryujinx.HLE.Loaders.Executables
             PrintRoSectionInfo();
         }
 
-        private int DecompressSection(NsoReader reader, NsoReader.SegmentType segmentType, int offset)
+        private uint DecompressSection(NsoReader reader, NsoReader.SegmentType segmentType, uint offset)
         {
             reader.GetSegmentSize(segmentType, out uint uncompressedSize).ThrowIfFailure();
 
-            var span = Program.AsSpan().Slice(offset, (int)uncompressedSize);
+            var span = Program.AsSpan().Slice((int)offset, (int)uncompressedSize);
 
             reader.ReadSegment(segmentType, span).ThrowIfFailure();
 
-            return (int)uncompressedSize;
+            return uncompressedSize;
         }
 
         private void PrintRoSectionInfo()
         {
             byte[]        roBuffer      = Ro.ToArray();
-            string        rawTextBuffer = Encoding.ASCII.GetString(roBuffer, 0, RoSize);
+            string        rawTextBuffer = Encoding.ASCII.GetString(roBuffer, 0, (int)RoSize);
             StringBuilder stringBuilder = new StringBuilder();
 
             int zero = BitConverter.ToInt32(roBuffer, 0);

+ 12 - 0
Ryujinx.Memory/IVirtualMemoryManager.cs

@@ -13,6 +13,18 @@ namespace Ryujinx.Memory
         void Write<T>(ulong va, T value) where T : unmanaged;
         void Write(ulong va, ReadOnlySpan<byte> data);
 
+        void Fill(ulong va, ulong size, byte value)
+        {
+            const int MaxChunkSize = 1 << 30;
+
+            for (ulong subOffset = 0; subOffset < size; subOffset += MaxChunkSize)
+            {
+                int copySize = (int)Math.Min(MaxChunkSize, size - subOffset);
+
+                GetWritableRegion(va + subOffset, copySize).Memory.Span.Fill(0);
+            }
+        }
+
         ReadOnlySpan<byte> GetSpan(ulong va, int size, bool tracked = false);
         WritableRegion GetWritableRegion(ulong va, int size);
         ref T GetRef<T>(ulong va) where T : unmanaged;