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,27 +3463,49 @@ public static partial class KernelMemoryCompatExports
return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT; return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT;
} }
if (offset >= DirectMemorySizeBytes)
{
// Real hardware returns EACCES here (0x8002000D), not ENOENT.
return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_DELETED;
}
var findNext = (flags & 1) != 0;
var found = false;
var matchStart = 0UL;
var matchEnd = 0UL;
var matchMemoryType = 0;
lock (_memoryGate) lock (_memoryGate)
{ {
foreach (var block in _directAllocations.Values) 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)
{ {
if (offset < block.Start || offset >= block.Start + block.Length) found = true;
{ matchStart = block.Start;
continue; matchEnd = block.Start + block.Length;
} matchMemoryType = block.MemoryType;
break;
if (!ctx.TryWriteUInt64(infoAddress, block.Start) ||
!ctx.TryWriteUInt64(infoAddress + sizeof(ulong), block.Start + block.Length) ||
!TryWriteInt32(ctx, infoAddress + (sizeof(ulong) * 2), block.MemoryType))
{
return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT;
}
return (int)OrbisGen2Result.ORBIS_GEN2_OK;
} }
} }
return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_NOT_FOUND; 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_OK;
} }
/// <summary> /// <summary>