aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.HLE/Loaders
diff options
context:
space:
mode:
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);