From 6fe51f970501fe732276c17ed0dacb564b92a73d Mon Sep 17 00:00:00 2001 From: riperiperi Date: Sat, 9 Jun 2018 01:15:02 +0100 Subject: [PATCH] ReadBytes function in AMemory, with cleaner range check. (#136) --- ChocolArm64/Memory/AMemory.cs | 20 +++++++++++ ChocolArm64/Memory/AMemoryHelper.cs | 12 ------- Ryujinx.Core/Gpu/NvGpuVmm.cs | 2 +- Ryujinx.Core/OsHle/Kernel/SvcSystem.cs | 2 +- .../OsHle/Services/Am/IStorageAccessor.cs | 2 +- .../OsHle/Services/Aud/IAudioDevice.cs | 4 +-- Ryujinx.Core/OsHle/Services/Aud/IAudioOut.cs | 3 +- Ryujinx.Core/OsHle/Services/Bsd/IClient.cs | 35 ++++++++----------- Ryujinx.Core/OsHle/Services/FspSrv/IFile.cs | 2 +- Ryujinx.Core/OsHle/Services/Lm/ILogger.cs | 3 +- .../Services/Set/ISystemSettingsServer.cs | 4 +-- .../OsHle/Services/Vi/IHOSBinderDriver.cs | 4 +-- 12 files changed, 46 insertions(+), 47 deletions(-) diff --git a/ChocolArm64/Memory/AMemory.cs b/ChocolArm64/Memory/AMemory.cs index c24a9e8ef..e7d46565f 100644 --- a/ChocolArm64/Memory/AMemory.cs +++ b/ChocolArm64/Memory/AMemory.cs @@ -301,6 +301,15 @@ namespace ChocolArm64.Memory return *((ulong*)(RamPtr + (uint)Position)); } + public byte[] ReadBytes(long Position, long Size) + { + EnsureRangeIsValid(Position, Size, AMemoryPerm.Read); + + byte[] Result = new byte[Size]; + Marshal.Copy((IntPtr)(RamPtr + (uint)Position), Result, 0, (int)Size); + return Result; + } + public Vector128 ReadVector8Unchecked(long Position) { if (Sse2.IsSupported) @@ -611,6 +620,17 @@ namespace ChocolArm64.Memory } } + private void EnsureRangeIsValid(long Position, long Size, AMemoryPerm Perm) + { + long EndPos = (Position + Size); + Position = Position & ~AMemoryMgr.PageMask; //check base of each page + while (Position < EndPos) + { + EnsureAccessIsValid(Position, Perm); + Position += AMemoryMgr.PageSize; + } + } + public void Dispose() { Dispose(true); diff --git a/ChocolArm64/Memory/AMemoryHelper.cs b/ChocolArm64/Memory/AMemoryHelper.cs index 1e3462985..c0ade89ce 100644 --- a/ChocolArm64/Memory/AMemoryHelper.cs +++ b/ChocolArm64/Memory/AMemoryHelper.cs @@ -22,18 +22,6 @@ namespace ChocolArm64.Memory } } - public static byte[] ReadBytes(AMemory Memory, long Position, long Size) - { - byte[] Data = new byte[Size]; - - for (long Offs = 0; Offs < Size; Offs++) - { - Data[Offs] = (byte)Memory.ReadByte(Position + Offs); - } - - return Data; - } - public static void WriteBytes(AMemory Memory, long Position, byte[] Data) { for (int Offs = 0; Offs < Data.Length; Offs++) diff --git a/Ryujinx.Core/Gpu/NvGpuVmm.cs b/Ryujinx.Core/Gpu/NvGpuVmm.cs index 1c408964f..09553b8ad 100644 --- a/Ryujinx.Core/Gpu/NvGpuVmm.cs +++ b/Ryujinx.Core/Gpu/NvGpuVmm.cs @@ -330,7 +330,7 @@ namespace Ryujinx.Core.Gpu { Position = GetPhysicalAddress(Position); - return AMemoryHelper.ReadBytes(Memory, Position, Size); + return Memory.ReadBytes(Position, Size); } public void WriteByte(long Position, byte Value) diff --git a/Ryujinx.Core/OsHle/Kernel/SvcSystem.cs b/Ryujinx.Core/OsHle/Kernel/SvcSystem.cs index 77f35c199..638625d82 100644 --- a/Ryujinx.Core/OsHle/Kernel/SvcSystem.cs +++ b/Ryujinx.Core/OsHle/Kernel/SvcSystem.cs @@ -233,7 +233,7 @@ namespace Ryujinx.Core.OsHle.Kernel { KThread CurrThread = Process.GetThread(ThreadState.Tpidr); - byte[] CmdData = AMemoryHelper.ReadBytes(Memory, CmdPtr, Size); + byte[] CmdData = Memory.ReadBytes(CmdPtr, Size); KSession Session = Process.HandleTable.GetData(Handle); diff --git a/Ryujinx.Core/OsHle/Services/Am/IStorageAccessor.cs b/Ryujinx.Core/OsHle/Services/Am/IStorageAccessor.cs index 0e928f678..4cd1f99b8 100644 --- a/Ryujinx.Core/OsHle/Services/Am/IStorageAccessor.cs +++ b/Ryujinx.Core/OsHle/Services/Am/IStorageAccessor.cs @@ -49,7 +49,7 @@ namespace Ryujinx.Core.OsHle.Services.Am Size = MaxSize; } - byte[] Data = AMemoryHelper.ReadBytes(Context.Memory, Position, Size); + byte[] Data = Context.Memory.ReadBytes(Position, Size); Buffer.BlockCopy(Data, 0, Storage.Data, (int)WritePosition, (int)Size); } diff --git a/Ryujinx.Core/OsHle/Services/Aud/IAudioDevice.cs b/Ryujinx.Core/OsHle/Services/Aud/IAudioDevice.cs index b5de85a13..73916f709 100644 --- a/Ryujinx.Core/OsHle/Services/Aud/IAudioDevice.cs +++ b/Ryujinx.Core/OsHle/Services/Aud/IAudioDevice.cs @@ -75,7 +75,7 @@ namespace Ryujinx.Core.OsHle.Services.Aud long Position = Context.Request.SendBuff[0].Position; long Size = Context.Request.SendBuff[0].Size; - byte[] DeviceNameBuffer = AMemoryHelper.ReadBytes(Context.Memory, Position, Size); + byte[] DeviceNameBuffer = Context.Memory.ReadBytes(Position, Size); string DeviceName = Encoding.ASCII.GetString(DeviceNameBuffer); @@ -160,7 +160,7 @@ namespace Ryujinx.Core.OsHle.Services.Aud (long Position, long Size) = Context.Request.GetBufferType0x21(); - byte[] DeviceNameBuffer = AMemoryHelper.ReadBytes(Context.Memory, Position, Size); + byte[] DeviceNameBuffer = Context.Memory.ReadBytes(Position, Size); string DeviceName = Encoding.UTF8.GetString(DeviceNameBuffer); diff --git a/Ryujinx.Core/OsHle/Services/Aud/IAudioOut.cs b/Ryujinx.Core/OsHle/Services/Aud/IAudioOut.cs index 09c5050fc..fba97a3f5 100644 --- a/Ryujinx.Core/OsHle/Services/Aud/IAudioOut.cs +++ b/Ryujinx.Core/OsHle/Services/Aud/IAudioOut.cs @@ -69,8 +69,7 @@ namespace Ryujinx.Core.OsHle.Services.Aud Context.Memory, Context.Request.SendBuff[0].Position); - byte[] Buffer = AMemoryHelper.ReadBytes( - Context.Memory, + byte[] Buffer = Context.Memory.ReadBytes( Data.SampleBufferPtr, Data.SampleBufferSize); diff --git a/Ryujinx.Core/OsHle/Services/Bsd/IClient.cs b/Ryujinx.Core/OsHle/Services/Bsd/IClient.cs index f26e5ee37..0c0eeb5a3 100644 --- a/Ryujinx.Core/OsHle/Services/Bsd/IClient.cs +++ b/Ryujinx.Core/OsHle/Services/Bsd/IClient.cs @@ -102,9 +102,8 @@ namespace Ryujinx.Core.OsHle.Services.Bsd //https://github.com/TuxSH/ftpd/blob/switch_pr/source/ftp.c#L1634 //https://linux.die.net/man/2/poll - byte[] SentBuffer = AMemoryHelper.ReadBytes(Context.Memory, - Context.Request.SendBuff[0].Position, - Context.Request.SendBuff[0].Size); + byte[] SentBuffer = Context.Memory.ReadBytes(Context.Request.SendBuff[0].Position, + Context.Request.SendBuff[0].Size); int SocketId = Get32(SentBuffer, 0); int RequestedEvents = Get16(SentBuffer, 4); @@ -152,9 +151,8 @@ namespace Ryujinx.Core.OsHle.Services.Bsd int SocketId = Context.RequestData.ReadInt32(); int SocketFlags = Context.RequestData.ReadInt32(); - byte[] SentBuffer = AMemoryHelper.ReadBytes(Context.Memory, - Context.Request.SendBuff[0].Position, - Context.Request.SendBuff[0].Size); + byte[] SentBuffer = Context.Memory.ReadBytes(Context.Request.SendBuff[0].Position, + Context.Request.SendBuff[0].Size); try { @@ -180,13 +178,11 @@ namespace Ryujinx.Core.OsHle.Services.Bsd int SocketId = Context.RequestData.ReadInt32(); int SocketFlags = Context.RequestData.ReadInt32(); - byte[] SentBuffer = AMemoryHelper.ReadBytes(Context.Memory, - Context.Request.SendBuff[0].Position, - Context.Request.SendBuff[0].Size); + byte[] SentBuffer = Context.Memory.ReadBytes(Context.Request.SendBuff[0].Position, + Context.Request.SendBuff[0].Size); - byte[] AddressBuffer = AMemoryHelper.ReadBytes(Context.Memory, - Context.Request.SendBuff[1].Position, - Context.Request.SendBuff[1].Size); + byte[] AddressBuffer = Context.Memory.ReadBytes(Context.Request.SendBuff[1].Position, + Context.Request.SendBuff[1].Size); if (!Sockets[SocketId].Handle.Connected) { @@ -291,9 +287,8 @@ namespace Ryujinx.Core.OsHle.Services.Bsd { int SocketId = Context.RequestData.ReadInt32(); - byte[] AddressBuffer = AMemoryHelper.ReadBytes(Context.Memory, - Context.Request.SendBuff[0].Position, - Context.Request.SendBuff[0].Size); + byte[] AddressBuffer = Context.Memory.ReadBytes(Context.Request.SendBuff[0].Position, + Context.Request.SendBuff[0].Size); try { @@ -316,9 +311,8 @@ namespace Ryujinx.Core.OsHle.Services.Bsd { int SocketId = Context.RequestData.ReadInt32(); - byte[] AddressBuffer = AMemoryHelper.ReadBytes(Context.Memory, - Context.Request.SendBuff[0].Position, - Context.Request.SendBuff[0].Size); + byte[] AddressBuffer = Context.Memory.ReadBytes(Context.Request.SendBuff[0].Position, + Context.Request.SendBuff[0].Size); try { @@ -369,9 +363,8 @@ namespace Ryujinx.Core.OsHle.Services.Bsd SocketOptionLevel SocketLevel = (SocketOptionLevel)Context.RequestData.ReadInt32(); SocketOptionName SocketOptionName = (SocketOptionName)Context.RequestData.ReadInt32(); - byte[] SocketOptionValue = AMemoryHelper.ReadBytes(Context.Memory, - Context.Request.PtrBuff[0].Position, - Context.Request.PtrBuff[0].Size); + byte[] SocketOptionValue = Context.Memory.ReadBytes(Context.Request.PtrBuff[0].Position, + Context.Request.PtrBuff[0].Size); int OptionValue = Get32(SocketOptionValue, 0); diff --git a/Ryujinx.Core/OsHle/Services/FspSrv/IFile.cs b/Ryujinx.Core/OsHle/Services/FspSrv/IFile.cs index bd7d138fd..0dd453855 100644 --- a/Ryujinx.Core/OsHle/Services/FspSrv/IFile.cs +++ b/Ryujinx.Core/OsHle/Services/FspSrv/IFile.cs @@ -62,7 +62,7 @@ namespace Ryujinx.Core.OsHle.Services.FspSrv long Offset = Context.RequestData.ReadInt64(); long Size = Context.RequestData.ReadInt64(); - byte[] Data = AMemoryHelper.ReadBytes(Context.Memory, Position, Size); + byte[] Data = Context.Memory.ReadBytes(Position, Size); BaseStream.Seek(Offset, SeekOrigin.Begin); BaseStream.Write(Data, 0, (int)Size); diff --git a/Ryujinx.Core/OsHle/Services/Lm/ILogger.cs b/Ryujinx.Core/OsHle/Services/Lm/ILogger.cs index c5b6c9313..510901058 100644 --- a/Ryujinx.Core/OsHle/Services/Lm/ILogger.cs +++ b/Ryujinx.Core/OsHle/Services/Lm/ILogger.cs @@ -23,8 +23,7 @@ namespace Ryujinx.Core.OsHle.Services.Lm public long Log(ServiceCtx Context) { - byte[] LogBuffer = AMemoryHelper.ReadBytes( - Context.Memory, + byte[] LogBuffer = Context.Memory.ReadBytes( Context.Request.PtrBuff[0].Position, Context.Request.PtrBuff[0].Size); diff --git a/Ryujinx.Core/OsHle/Services/Set/ISystemSettingsServer.cs b/Ryujinx.Core/OsHle/Services/Set/ISystemSettingsServer.cs index 26d676938..820942913 100644 --- a/Ryujinx.Core/OsHle/Services/Set/ISystemSettingsServer.cs +++ b/Ryujinx.Core/OsHle/Services/Set/ISystemSettingsServer.cs @@ -97,8 +97,8 @@ namespace Ryujinx.Core.OsHle.Services.Set long ReplyPos = Context.Request.ReceiveBuff[0].Position; long ReplySize = Context.Request.ReceiveBuff[0].Size; - byte[] Class = AMemoryHelper.ReadBytes(Context.Memory, ClassPos, ClassSize); - byte[] Name = AMemoryHelper.ReadBytes(Context.Memory, NamePos, NameSize); + byte[] Class = Context.Memory.ReadBytes(ClassPos, ClassSize); + byte[] Name = Context.Memory.ReadBytes(NamePos, NameSize); string AskedSetting = Encoding.ASCII.GetString(Class).Trim('\0') + "!" + Encoding.ASCII.GetString(Name).Trim('\0'); diff --git a/Ryujinx.Core/OsHle/Services/Vi/IHOSBinderDriver.cs b/Ryujinx.Core/OsHle/Services/Vi/IHOSBinderDriver.cs index c00e247e2..41c3970e7 100644 --- a/Ryujinx.Core/OsHle/Services/Vi/IHOSBinderDriver.cs +++ b/Ryujinx.Core/OsHle/Services/Vi/IHOSBinderDriver.cs @@ -41,7 +41,7 @@ namespace Ryujinx.Core.OsHle.Services.Vi long DataPos = Context.Request.SendBuff[0].Position; long DataSize = Context.Request.SendBuff[0].Size; - byte[] Data = AMemoryHelper.ReadBytes(Context.Memory, DataPos, DataSize); + byte[] Data = Context.Memory.ReadBytes(DataPos, DataSize); Data = Parcel.GetParcelData(Data); @@ -55,7 +55,7 @@ namespace Ryujinx.Core.OsHle.Services.Vi (long DataPos, long DataSize) = Context.Request.GetBufferType0x21(); - byte[] Data = AMemoryHelper.ReadBytes(Context.Memory, DataPos, DataSize); + byte[] Data = Context.Memory.ReadBytes(DataPos, DataSize); Data = Parcel.GetParcelData(Data);