From 6aa78bb55baee8700d669c06decacb6e961e8403 Mon Sep 17 00:00:00 2001 From: h4sht Date: Tue, 21 Jul 2026 17:18:58 +0200 Subject: [PATCH] [Loader] Fall back to fixed-range backfill when main image base is occupied (#493) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When TryAllocateAtExact fails for the main image base (0x800000000 for PS5, 0x400000 for PS4), the loader previously threw a fatal InvalidOperationException with no recovery path. This happens when the host OS has already claimed part of that address range — common under Rosetta 2, with aggressive ASLR, or when another process maps into the guest address space. Instead of failing immediately, attempt TryBackFixedRange which backs the range page by page, claiming any free gaps. If the backfill also fails, Clear() rolls back partial allocations and the exception now includes platform-specific recovery advice. This prevents the most common emulator startup crash on affected hosts. Co-authored-by: tru3 --- src/SharpEmu.Core/Loader/SelfLoader.cs | 29 +++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/src/SharpEmu.Core/Loader/SelfLoader.cs b/src/SharpEmu.Core/Loader/SelfLoader.cs index 3c29a6b7..ec032cdb 100644 --- a/src/SharpEmu.Core/Loader/SelfLoader.cs +++ b/src/SharpEmu.Core/Loader/SelfLoader.cs @@ -199,9 +199,32 @@ public sealed class SelfLoader : ISelfLoader { if (!physicalVm.TryAllocateAtExact(imageBase, totalImageSize, executable: true, out var allocatedBase)) { - var reason = physicalVm.DescribeAddressForDiagnostics(imageBase); - throw new InvalidOperationException( - $"Could not allocate main image at required base 0x{imageBase:X16} (size=0x{totalImageSize:X}): {reason}."); + // Exact allocation failed — the host may have already claimed + // part of this range (ASLR, Rosetta 2, or another process). + // Try backing the fixed range page by page to claim whatever + // free gaps exist. If the whole range is occupied the backfill + // returns false and we surface the original failure reason. + Console.Error.WriteLine( + $"[LOADER] Exact allocation at main image base 0x{imageBase:X16} " + + $"(size=0x{totalImageSize:X}) failed; attempting fixed-range backfill."); + if (!physicalVm.TryBackFixedRange(imageBase, totalImageSize, executable: true)) + { + // TryBackFixedRange may have partially backed pages before + // failing. The earlier Clear() already reset all regions, so + // this second Clear() is idempotent for everything except the + // partial backfill — it frees only those orphaned pages. + physicalVm.Clear(); + var reason = physicalVm.DescribeAddressForDiagnostics(imageBase); + throw new InvalidOperationException( + $"Could not allocate main image at required base 0x{imageBase:X16} " + + $"(size=0x{totalImageSize:X}): {reason}. " + + "Try closing other applications, rebooting, or " + + (OperatingSystem.IsWindows() + ? "setting SHARPEMU_DISABLE_MITIGATION_RELAUNCH=1." + : "ensuring no other process maps into this address range.")); + } + + allocatedBase = imageBase; } imageBase = allocatedBase;