Jelajahi Sumber

Move WriteBytes to AMemory, implement it with a Marshal copy like ReadBytes, fix regression on address range checking

gdkchan 7 tahun lalu
induk
melakukan
7f5a8effbb

+ 34 - 25
ChocolArm64/Memory/AMemory.cs

@@ -353,22 +353,6 @@ namespace ChocolArm64.Memory
             return *((ulong*)(RamPtr + (uint)Position));
         }
 
-        public byte[] ReadBytes(long Position, long Size)
-        {
-            if ((uint)Size > int.MaxValue)
-            {
-                throw new ArgumentOutOfRangeException(nameof(Size));
-            }
-
-            EnsureRangeIsValid(Position, Size, AMemoryPerm.Read);
-
-            byte[] Data = new byte[Size];
-
-            Marshal.Copy((IntPtr)(RamPtr + (uint)Position), Data, 0, (int)Size);
-
-            return Data;
-        }
-
         public Vector128<float> ReadVector8Unchecked(long Position)
         {
             if (Sse2.IsSupported)
@@ -433,6 +417,22 @@ namespace ChocolArm64.Memory
             }
         }
 
+        public byte[] ReadBytes(long Position, long Size)
+        {
+            if ((uint)Size > int.MaxValue)
+            {
+                throw new ArgumentOutOfRangeException(nameof(Size));
+            }
+
+            EnsureRangeIsValid(Position, Size, AMemoryPerm.Read);
+
+            byte[] Data = new byte[Size];
+
+            Marshal.Copy((IntPtr)(RamPtr + (uint)Position), Data, 0, (int)Size);
+
+            return Data;
+        }
+
         public void WriteSByte(long Position, sbyte Value)
         {
             WriteByte(Position, (byte)Value);
@@ -666,23 +666,19 @@ namespace ChocolArm64.Memory
             }
         }
 
-        private void EnsureAccessIsValid(long Position, AMemoryPerm Perm)
+        public void WriteBytes(long Position, byte[] Data)
         {
-            if (!Manager.IsMapped(Position))
-            {
-                throw new VmmPageFaultException(Position);
-            }
+            EnsureRangeIsValid(Position, (uint)Data.Length, AMemoryPerm.Write);
 
-            if (!Manager.HasPermission(Position, Perm))
-            {
-                throw new VmmAccessViolationException(Position, Perm);
-            }
+            Marshal.Copy(Data, 0, (IntPtr)(RamPtr + (uint)Position), Data.Length);
         }
 
         private void EnsureRangeIsValid(long Position, long Size, AMemoryPerm Perm)
         {
             long EndPos = Position + Size;
 
+            Position &= ~AMemoryMgr.PageMask;
+
             while ((ulong)Position < (ulong)EndPos)
             {
                 EnsureAccessIsValid(Position, Perm);
@@ -691,6 +687,19 @@ namespace ChocolArm64.Memory
             }
         }
 
+        private void EnsureAccessIsValid(long Position, AMemoryPerm Perm)
+        {
+            if (!Manager.IsMapped(Position))
+            {
+                throw new VmmPageFaultException(Position);
+            }
+
+            if (!Manager.HasPermission(Position, Perm))
+            {
+                throw new VmmAccessViolationException(Position, Perm);
+            }
+        }
+
         public void Dispose()
         {
             Dispose(true);

+ 0 - 8
ChocolArm64/Memory/AMemoryHelper.cs

@@ -22,14 +22,6 @@ namespace ChocolArm64.Memory
             }
         }
 
-        public static void WriteBytes(AMemory Memory, long Position, byte[] Data)
-        {
-            for (int Offs = 0; Offs < Data.Length; Offs++)
-            {
-                Memory.WriteByte(Position + Offs, Data[Offs]);
-            }
-        }
-
         public unsafe static T Read<T>(AMemory Memory, long Position) where T : struct
         {
             long Size = Marshal.SizeOf<T>();

+ 1 - 1
Ryujinx.Core/Gpu/NvGpuVmm.cs

@@ -404,7 +404,7 @@ namespace Ryujinx.Core.Gpu
         {
             Position = GetPhysicalAddress(Position);
 
-            AMemoryHelper.WriteBytes(Memory, Position, Data);
+            Memory.WriteBytes(Position, Data);
         }
     }
 }

+ 1 - 1
Ryujinx.Core/Loaders/Executable.cs

@@ -102,7 +102,7 @@ namespace Ryujinx.Core.Loaders
         {
             Memory.Manager.Map(Position, Data.Length, (int)Type, AMemoryPerm.Write);
 
-            AMemoryHelper.WriteBytes(Memory, Position, Data);
+            Memory.WriteBytes(Position, Data);
 
             Memory.Manager.Reprotect(Position, Data.Length, Perm);
         }

+ 1 - 1
Ryujinx.Core/OsHle/Ipc/IpcHandler.cs

@@ -92,7 +92,7 @@ namespace Ryujinx.Core.OsHle.Ipc
                     throw new NotImplementedException(Request.Type.ToString());
                 }
 
-                AMemoryHelper.WriteBytes(Memory, CmdPtr, Response.GetBytes(CmdPtr));
+                Memory.WriteBytes(CmdPtr, Response.GetBytes(CmdPtr));
             }
 
             return 0;

+ 1 - 2
Ryujinx.Core/OsHle/Services/Am/IStorageAccessor.cs

@@ -1,4 +1,3 @@
-using ChocolArm64.Memory;
 using Ryujinx.Core.OsHle.Ipc;
 using System;
 using System.Collections.Generic;
@@ -76,7 +75,7 @@ namespace Ryujinx.Core.OsHle.Services.Am
                 Data = Storage.Data;
             }
 
-            AMemoryHelper.WriteBytes(Context.Memory, Position, Data);
+            Context.Memory.WriteBytes(Position, Data);
 
             return 0;
         }

+ 4 - 5
Ryujinx.Core/OsHle/Services/Aud/IAudioDevice.cs

@@ -1,4 +1,3 @@
-using ChocolArm64.Memory;
 using Ryujinx.Core.Logging;
 using Ryujinx.Core.OsHle.Handles;
 using Ryujinx.Core.OsHle.Ipc;
@@ -60,7 +59,7 @@ namespace Ryujinx.Core.OsHle.Services.Aud
                     break;
                 }
 
-                AMemoryHelper.WriteBytes(Context.Memory, Position, Buffer);
+                Context.Memory.WriteBytes(Position, Buffer);
 
                 Position += Buffer.Length;
             }
@@ -95,7 +94,7 @@ namespace Ryujinx.Core.OsHle.Services.Aud
 
             if ((ulong)DeviceNameBuffer.Length <= (ulong)Size)
             {
-                AMemoryHelper.WriteBytes(Context.Memory, Position, DeviceNameBuffer);
+                Context.Memory.WriteBytes(Position, DeviceNameBuffer);
             }
             else
             {
@@ -146,7 +145,7 @@ namespace Ryujinx.Core.OsHle.Services.Aud
                     break;
                 }
 
-                AMemoryHelper.WriteBytes(Context.Memory, Position, Buffer);
+                Context.Memory.WriteBytes(Position, Buffer);
 
                 Position += Buffer.Length;
             }
@@ -188,7 +187,7 @@ namespace Ryujinx.Core.OsHle.Services.Aud
 
             if ((ulong)DeviceNameBuffer.Length <= (ulong)Size)
             {
-                AMemoryHelper.WriteBytes(Context.Memory, Position, DeviceNameBuffer);
+                Context.Memory.WriteBytes(Position, DeviceNameBuffer);
             }
             else
             {

+ 2 - 2
Ryujinx.Core/OsHle/Services/Aud/IAudioOutManager.cs

@@ -36,7 +36,7 @@ namespace Ryujinx.Core.OsHle.Services.Aud
 
             if ((ulong)DeviceNameBuffer.Length <= (ulong)Size)
             {
-                AMemoryHelper.WriteBytes(Context.Memory, Position, DeviceNameBuffer);
+                Context.Memory.WriteBytes(Position, DeviceNameBuffer);
 
                 NameCount++;
             }
@@ -71,7 +71,7 @@ namespace Ryujinx.Core.OsHle.Services.Aud
 
             if ((ulong)DeviceNameBuffer.Length <= (ulong)Size)
             {
-                AMemoryHelper.WriteBytes(Context.Memory, Position, DeviceNameBuffer);
+                Context.Memory.WriteBytes(Position, DeviceNameBuffer);
             }
             else
             {

+ 2 - 3
Ryujinx.Core/OsHle/Services/Bsd/IClient.cs

@@ -1,4 +1,3 @@
-using ChocolArm64.Memory;
 using Ryujinx.Core.OsHle.Ipc;
 using Ryujinx.Core.OsHle.Utilities;
 using System.Collections.Generic;
@@ -131,7 +130,7 @@ namespace Ryujinx.Core.OsHle.Services.Bsd
 
                 //Logging.Debug("Received Buffer:" + Environment.NewLine + Logging.HexDump(ReceivedBuffer));
 
-                AMemoryHelper.WriteBytes(Context.Memory, Context.Request.ReceiveBuff[0].Position, ReceivedBuffer);
+                Context.Memory.WriteBytes(Context.Request.ReceiveBuff[0].Position, ReceivedBuffer);
 
                 Context.ResponseData.Write(BytesRead);
                 Context.ResponseData.Write(0);
@@ -266,7 +265,7 @@ namespace Ryujinx.Core.OsHle.Services.Bsd
 
                     Writer.Write(IpAddress);
 
-                    AMemoryHelper.WriteBytes(Context.Memory, AddrBufferPtr, MS.ToArray());
+                    Context.Memory.WriteBytes(AddrBufferPtr, MS.ToArray());
 
                     Context.ResponseData.Write(Sockets.Count - 1);
                     Context.ResponseData.Write(0);

+ 1 - 2
Ryujinx.Core/OsHle/Services/FspSrv/IDirectory.cs

@@ -1,4 +1,3 @@
-using ChocolArm64.Memory;
 using Ryujinx.Core.OsHle.Ipc;
 using System;
 using System.Collections.Generic;
@@ -78,7 +77,7 @@ namespace Ryujinx.Core.OsHle.Services.FspSrv
 
             byte[] NameBuffer = Encoding.UTF8.GetBytes(Path.GetFileName(FullPath));
 
-            AMemoryHelper.WriteBytes(Context.Memory, Position, NameBuffer);
+            Context.Memory.WriteBytes(Position, NameBuffer);
 
             int  Type = 0;
             long Size = 0;

+ 1 - 2
Ryujinx.Core/OsHle/Services/FspSrv/IFile.cs

@@ -1,4 +1,3 @@
-using ChocolArm64.Memory;
 using Ryujinx.Core.OsHle.Ipc;
 using System;
 using System.Collections.Generic;
@@ -47,7 +46,7 @@ namespace Ryujinx.Core.OsHle.Services.FspSrv
 
             int ReadSize = BaseStream.Read(Data, 0, (int)Size);
 
-            AMemoryHelper.WriteBytes(Context.Memory, Position, Data);
+            Context.Memory.WriteBytes(Position, Data);
 
             Context.ResponseData.Write((long)ReadSize);
 

+ 1 - 2
Ryujinx.Core/OsHle/Services/FspSrv/IStorage.cs

@@ -1,4 +1,3 @@
-using ChocolArm64.Memory;
 using Ryujinx.Core.OsHle.Ipc;
 using System.Collections.Generic;
 using System.IO;
@@ -43,7 +42,7 @@ namespace Ryujinx.Core.OsHle.Services.FspSrv
                 BaseStream.Seek(Offset, SeekOrigin.Begin);
                 BaseStream.Read(Data, 0, Data.Length);
 
-                AMemoryHelper.WriteBytes(Context.Memory, BuffDesc.Position, Data);
+                Context.Memory.WriteBytes(BuffDesc.Position, Data);
             }
 
             return 0;

+ 17 - 15
Ryujinx.Core/OsHle/Services/Set/ISystemSettingsServer.cs

@@ -1,4 +1,3 @@
-using ChocolArm64.Memory;
 using Ryujinx.Core.OsHle.Ipc;
 using Ryujinx.Core.Settings;
 using System;
@@ -30,17 +29,17 @@ namespace Ryujinx.Core.OsHle.Services.Set
             long ReplyPos  = Context.Request.RecvListBuff[0].Position;
             long ReplySize = Context.Request.RecvListBuff[0].Size;
 
-            byte MajorFWVersion = 0x03;
-            byte MinorFWVersion = 0x00;
-            byte MicroFWVersion = 0x00;
-            byte Unknown        = 0x00; //Build?
+            const byte MajorFWVersion = 0x03;
+            const byte MinorFWVersion = 0x00;
+            const byte MicroFWVersion = 0x00;
+            const byte Unknown        = 0x00; //Build?
 
-            int RevisionNumber  = 0x0A;
+            const int RevisionNumber = 0x0A;
 
-            string Platform     = "NX";
-            string UnknownHex   = "7fbde2b0bba4d14107bf836e4643043d9f6c8e47";
-            string Version      = "3.0.0";
-            string Build        = "NintendoSDK Firmware for NX 3.0.0-10.0";
+            const string Platform   = "NX";
+            const string UnknownHex = "7fbde2b0bba4d14107bf836e4643043d9f6c8e47";
+            const string Version    = "3.0.0";
+            const string Build      = "NintendoSDK Firmware for NX 3.0.0-10.0";
 
             //http://switchbrew.org/index.php?title=System_Version_Title
             using (MemoryStream MS = new MemoryStream(0x100))
@@ -57,15 +56,18 @@ namespace Ryujinx.Core.OsHle.Services.Set
                 Writer.Write(Encoding.ASCII.GetBytes(Platform));
 
                 MS.Seek(0x28, SeekOrigin.Begin);
+
                 Writer.Write(Encoding.ASCII.GetBytes(UnknownHex));
 
                 MS.Seek(0x68, SeekOrigin.Begin);
+
                 Writer.Write(Encoding.ASCII.GetBytes(Version));
 
                 MS.Seek(0x80, SeekOrigin.Begin);
+
                 Writer.Write(Encoding.ASCII.GetBytes(Build));
 
-                AMemoryHelper.WriteBytes(Context.Memory, ReplyPos, MS.ToArray());
+                Context.Memory.WriteBytes(ReplyPos, MS.ToArray());
             }
 
             return 0;
@@ -85,7 +87,7 @@ namespace Ryujinx.Core.OsHle.Services.Set
             Context.Ns.Settings.ThemeColor = (ColorSet)ColorSetId;
             return 0;
         }
-        
+
         public static long GetSettingsItemValue(ServiceCtx Context)
         {
             long ClassPos  = Context.Request.PtrBuff[0].Position;
@@ -111,11 +113,11 @@ namespace Ryujinx.Core.OsHle.Services.Set
                 if (NxSetting is string StringValue)
                 {
                     if (StringValue.Length + 1 > ReplySize)
-                    { 
+                    {
                         Context.Ns.Log.PrintError(Logging.LogClass.ServiceSet, $"{AskedSetting} String value size is too big!");
                     }
                     else
-                    { 
+                    {
                         SettingBuffer = Encoding.ASCII.GetBytes(StringValue + "\0");
                     }
                 }
@@ -132,7 +134,7 @@ namespace Ryujinx.Core.OsHle.Services.Set
                     throw new NotImplementedException(NxSetting.GetType().Name);
                 }
 
-                AMemoryHelper.WriteBytes(Context.Memory, ReplyPos, SettingBuffer);
+                Context.Memory.WriteBytes(ReplyPos, SettingBuffer);
 
                 Context.Ns.Log.PrintDebug(Logging.LogClass.ServiceSet, $"{AskedSetting} set value: {NxSetting} as {NxSetting.GetType()}");
             }

+ 2 - 3
Ryujinx.Core/OsHle/Services/Vi/IApplicationDisplayService.cs

@@ -1,4 +1,3 @@
-using ChocolArm64.Memory;
 using Ryujinx.Core.OsHle.Ipc;
 using System.Collections.Generic;
 using System.IO;
@@ -104,7 +103,7 @@ namespace Ryujinx.Core.OsHle.Services.Vi
 
             byte[] Parcel = MakeIGraphicsBufferProducer(ParcelPtr);
 
-            AMemoryHelper.WriteBytes(Context.Memory, ParcelPtr, Parcel);
+            Context.Memory.WriteBytes(ParcelPtr, Parcel);
 
             Context.ResponseData.Write((long)Parcel.Length);
 
@@ -129,7 +128,7 @@ namespace Ryujinx.Core.OsHle.Services.Vi
 
             byte[] Parcel = MakeIGraphicsBufferProducer(ParcelPtr);
 
-            AMemoryHelper.WriteBytes(Context.Memory, ParcelPtr, Parcel);
+            Context.Memory.WriteBytes(ParcelPtr, Parcel);
 
             Context.ResponseData.Write(0L);
             Context.ResponseData.Write((long)Parcel.Length);

+ 2 - 2
Ryujinx.Core/OsHle/Services/Vi/NvFlinger.cs

@@ -1,4 +1,3 @@
-using ChocolArm64.Memory;
 using Ryujinx.Core.Gpu;
 using Ryujinx.Core.Logging;
 using Ryujinx.Core.OsHle.Handles;
@@ -9,6 +8,7 @@ using System.Collections.Generic;
 using System.IO;
 using System.Text;
 using System.Threading;
+
 using static Ryujinx.Core.OsHle.Services.Android.Parcel;
 
 namespace Ryujinx.Core.OsHle.Services.Android
@@ -272,7 +272,7 @@ namespace Ryujinx.Core.OsHle.Services.Android
 
             byte[] Reply = MakeParcel(Data, new byte[0]);
 
-            AMemoryHelper.WriteBytes(Context.Memory, ReplyPos, Reply);
+            Context.Memory.WriteBytes(ReplyPos, Reply);
 
             return 0;
         }