aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.HLE/Loaders
diff options
context:
space:
mode:
authorThomas Guillemard <thog@protonmail.com>2018-10-10 01:01:49 +0200
committerAc_K <Acoustik666@gmail.com>2018-10-10 01:01:49 +0200
commitd5c0de8362941f957846a71d09a40a6eb77a22fa (patch)
tree23a6e5939e814d0a02314523343a5c3ad784bbe8 /Ryujinx.HLE/Loaders
parent65c67bb4a5d19d81048fd84c3ec599ff531629fd (diff)
Implement IRoInterface (#445)
* Implement IRoInterface This is required by Super Mario Party. This commit also adds MapProcessCodeMemory and UnmapProcessCodeMemory functions in KMemoryManager. Those two calls might not reflect what the SVC of the same names do. * Fix some code style issues * Use MakeError to clarify error code * Add NRR and NRO constants * Fix some codestyle issues * Fix InvalidMemoryState error code
Diffstat (limited to 'Ryujinx.HLE/Loaders')
-rw-r--r--Ryujinx.HLE/Loaders/Executable.cs44
-rw-r--r--Ryujinx.HLE/Loaders/Executables/IExecutable.cs3
-rw-r--r--Ryujinx.HLE/Loaders/Executables/Nro.cs9
-rw-r--r--Ryujinx.HLE/Loaders/Executables/Nso.cs6
4 files changed, 52 insertions, 10 deletions
diff --git a/Ryujinx.HLE/Loaders/Executable.cs b/Ryujinx.HLE/Loaders/Executable.cs
index a9850e4a..3c63af14 100644
--- a/Ryujinx.HLE/Loaders/Executable.cs
+++ b/Ryujinx.HLE/Loaders/Executable.cs
@@ -49,21 +49,49 @@ namespace Ryujinx.HLE.Loaders
long DataPosition = ImageBase + (uint)Exe.DataOffset;
long TextSize = (uint)IntUtils.AlignUp(Exe.Text.Length, KMemoryManager.PageSize);
- long ROSize = (uint)IntUtils.AlignUp(Exe.RO.Length, KMemoryManager.PageSize);
+ long ROSize = (uint)IntUtils.AlignUp(Exe.RO.Length, KMemoryManager.PageSize);
long DataSize = (uint)IntUtils.AlignUp(Exe.Data.Length, KMemoryManager.PageSize);
+ long BssSize = (uint)IntUtils.AlignUp(Exe.BssSize, KMemoryManager.PageSize);
- long DataAndBssSize = (uint)IntUtils.AlignUp(Exe.BssSize, KMemoryManager.PageSize) + DataSize;
+ long DataAndBssSize = BssSize + DataSize;
ImageEnd = DataPosition + DataAndBssSize;
- MemoryManager.HleMapProcessCode(TextPosition, TextSize + ROSize + DataAndBssSize);
+ if (Exe.SourceAddress == 0)
+ {
+ MemoryManager.HleMapProcessCode(TextPosition, TextSize + ROSize + DataAndBssSize);
+
+ MemoryManager.SetProcessMemoryPermission(ROPosition, ROSize, MemoryPermission.Read);
+ MemoryManager.SetProcessMemoryPermission(DataPosition, DataAndBssSize, MemoryPermission.ReadAndWrite);
- MemoryManager.SetProcessMemoryPermission(ROPosition, ROSize, MemoryPermission.Read);
- MemoryManager.SetProcessMemoryPermission(DataPosition, DataAndBssSize, MemoryPermission.ReadAndWrite);
+ Memory.WriteBytes(TextPosition, Exe.Text);
+ Memory.WriteBytes(ROPosition, Exe.RO);
+ Memory.WriteBytes(DataPosition, Exe.Data);
+ }
+ else
+ {
+ long Result = MemoryManager.MapProcessCodeMemory(TextPosition, Exe.SourceAddress, TextSize + ROSize + DataSize);
+
+ if (Result != 0)
+ {
+ throw new InvalidOperationException();
+ }
- Memory.WriteBytes(TextPosition, Exe.Text);
- Memory.WriteBytes(ROPosition, Exe.RO);
- Memory.WriteBytes(DataPosition, Exe.Data);
+ MemoryManager.SetProcessMemoryPermission(ROPosition, ROSize, MemoryPermission.Read);
+ MemoryManager.SetProcessMemoryPermission(DataPosition, DataSize, MemoryPermission.ReadAndWrite);
+
+ if (Exe.BssAddress != 0 && Exe.BssSize != 0)
+ {
+ Result = MemoryManager.MapProcessCodeMemory(DataPosition + DataSize, Exe.BssAddress, BssSize);
+
+ if (Result != 0)
+ {
+ throw new InvalidOperationException();
+ }
+
+ MemoryManager.SetProcessMemoryPermission(DataPosition + DataSize, BssSize, MemoryPermission.ReadAndWrite);
+ }
+ }
if (Exe.Mod0Offset == 0)
{
diff --git a/Ryujinx.HLE/Loaders/Executables/IExecutable.cs b/Ryujinx.HLE/Loaders/Executables/IExecutable.cs
index 44bad614..6f0952ab 100644
--- a/Ryujinx.HLE/Loaders/Executables/IExecutable.cs
+++ b/Ryujinx.HLE/Loaders/Executables/IExecutable.cs
@@ -8,6 +8,9 @@ namespace Ryujinx.HLE.Loaders.Executables
byte[] RO { get; }
byte[] Data { get; }
+ long SourceAddress { get; }
+ long BssAddress { get; }
+
int Mod0Offset { get; }
int TextOffset { get; }
int ROOffset { get; }
diff --git a/Ryujinx.HLE/Loaders/Executables/Nro.cs b/Ryujinx.HLE/Loaders/Executables/Nro.cs
index 0b5068d7..6015da21 100644
--- a/Ryujinx.HLE/Loaders/Executables/Nro.cs
+++ b/Ryujinx.HLE/Loaders/Executables/Nro.cs
@@ -16,9 +16,14 @@ namespace Ryujinx.HLE.Loaders.Executables
public int DataOffset { get; private set; }
public int BssSize { get; private set; }
- public Nro(Stream Input, string FilePath)
+ public long SourceAddress { get; private set; }
+ public long BssAddress { get; private set; }
+
+ public Nro(Stream Input, string FilePath, long SourceAddress = 0, long BssAddress = 0)
{
- this.FilePath = FilePath;
+ this.FilePath = FilePath;
+ this.SourceAddress = SourceAddress;
+ this.BssAddress = BssAddress;
BinaryReader Reader = new BinaryReader(Input);
diff --git a/Ryujinx.HLE/Loaders/Executables/Nso.cs b/Ryujinx.HLE/Loaders/Executables/Nso.cs
index fef9c4b8..c7b48a5f 100644
--- a/Ryujinx.HLE/Loaders/Executables/Nso.cs
+++ b/Ryujinx.HLE/Loaders/Executables/Nso.cs
@@ -18,6 +18,9 @@ namespace Ryujinx.HLE.Loaders.Executables
public int DataOffset { get; private set; }
public int BssSize { get; private set; }
+ public long SourceAddress { get; private set; }
+ public long BssAddress { get; private set; }
+
[Flags]
private enum NsoFlags
{
@@ -33,6 +36,9 @@ namespace Ryujinx.HLE.Loaders.Executables
{
this.FilePath = FilePath;
+ SourceAddress = 0;
+ BssAddress = 0;
+
BinaryReader Reader = new BinaryReader(Input);
Input.Seek(0, SeekOrigin.Begin);