Fix NID BHouLQzh0X0, doubled StartupStaticTlsReservation memory. Both needed to launch GTA V. (#454)

* Increased StartupStaticTlsReservation (doubled) and fixed mistake in NID BHouLQzh0X0. Now GTA V RAGE engine seems to start loading.

* fixed NID BHouLQzh0X0, this had an issue causing GTA V not to load. Also doubled StartupStaticTlsReservation.

* Removed .vscode folder and reverted global.json
This commit is contained in:
Job Meijer
2026-07-20 13:37:30 +02:00
committed by GitHub
parent db9b20481c
commit a1cbff8a9c
3 changed files with 40 additions and 17 deletions
+1
View File
@@ -42,3 +42,4 @@ ehthumbs.db
.vs/ .vs/
.idea/ .idea/
.vscode/
+1 -1
View File
@@ -17,7 +17,7 @@ public static class GuestTlsTemplate
// Must match CpuDispatcher/DirectExecutionBackend's mapped prefix. PS5 // Must match CpuDispatcher/DirectExecutionBackend's mapped prefix. PS5
// modules can require more than one host page of Variant II static TLS; // modules can require more than one host page of Variant II static TLS;
// Dreaming Sarah's startup image, for example, reaches 0x1870 bytes. // Dreaming Sarah's startup image, for example, reaches 0x1870 bytes.
public const ulong StartupStaticTlsReservation = 0x10000UL; public const ulong StartupStaticTlsReservation = 0x20000UL; // Was 0x10000UL, but thats too small for GTA V
private static readonly object _gate = new(); private static readonly object _gate = new();
private static readonly SortedDictionary<ulong, ModuleTemplate> _modules = new(); private static readonly SortedDictionary<ulong, ModuleTemplate> _modules = new();
private static readonly Dictionary<ulong, ThreadDtv> _threadDtvs = new(); private static readonly Dictionary<ulong, ThreadDtv> _threadDtvs = new();
@@ -3455,7 +3455,7 @@ public static partial class KernelMemoryCompatExports
public static int KernelDirectMemoryQuery(CpuContext ctx) public static int KernelDirectMemoryQuery(CpuContext ctx)
{ {
var offset = ctx[CpuRegister.Rdi]; var offset = ctx[CpuRegister.Rdi];
_ = ctx[CpuRegister.Rsi]; // flags var flags = ctx[CpuRegister.Rsi];
var infoAddress = ctx[CpuRegister.Rdx]; var infoAddress = ctx[CpuRegister.Rdx];
var infoSize = ctx[CpuRegister.Rcx]; var infoSize = ctx[CpuRegister.Rcx];
if (infoAddress == 0 || infoSize < 24) if (infoAddress == 0 || infoSize < 24)
@@ -3463,28 +3463,50 @@ public static partial class KernelMemoryCompatExports
return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT; return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT;
} }
lock (_memoryGate) if (offset >= DirectMemorySizeBytes)
{ {
foreach (var block in _directAllocations.Values) // Real hardware returns EACCES here (0x8002000D), not ENOENT.
{ return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_DELETED;
if (offset < block.Start || offset >= block.Start + block.Length)
{
continue;
} }
if (!ctx.TryWriteUInt64(infoAddress, block.Start) || var findNext = (flags & 1) != 0;
!ctx.TryWriteUInt64(infoAddress + sizeof(ulong), block.Start + block.Length) || var found = false;
!TryWriteInt32(ctx, infoAddress + (sizeof(ulong) * 2), block.MemoryType)) var matchStart = 0UL;
var matchEnd = 0UL;
var matchMemoryType = 0;
lock (_memoryGate)
{
var candidates = _directAllocations.Values
.Where(block => findNext
? block.Start + block.Length > offset
: offset >= block.Start && offset < block.Start + block.Length)
.OrderBy(block => block.Start);
foreach (var block in candidates)
{
found = true;
matchStart = block.Start;
matchEnd = block.Start + block.Length;
matchMemoryType = block.MemoryType;
break;
}
}
if (!found)
{
return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_DELETED;
}
if (!ctx.TryWriteUInt64(infoAddress, matchStart) ||
!ctx.TryWriteUInt64(infoAddress + sizeof(ulong), matchEnd) ||
!TryWriteInt32(ctx, infoAddress + (sizeof(ulong) * 2), matchMemoryType))
{ {
return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT; return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT;
} }
return (int)OrbisGen2Result.ORBIS_GEN2_OK; return (int)OrbisGen2Result.ORBIS_GEN2_OK;
} }
}
return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_NOT_FOUND;
}
/// <summary> /// <summary>
/// POSIX alias of <see cref="KernelMprotect"/>; identical (addr, len, prot) /// POSIX alias of <see cref="KernelMprotect"/>; identical (addr, len, prot)