mirror of
https://github.com/par274/sharpemu.git
synced 2026-07-16 01:51:17 +00:00
Fix macOS exact-address mmap falling back to MAP_FIXED (#214)
The PS5 image loader requires guest images to land at fixed virtual addresses (e.g. the 32 GiB main image base). On macOS the exact-address mmap path only ever passed that address as a hint, never MAP_FIXED, to avoid clobbering untracked host mappings (dyld, JIT heap, Rosetta). On Apple Silicon under Rosetta 2 the kernel does not reliably honor that hint, so the allocation failed deterministically before a single guest instruction ran (reported in #194). Retry with true MAP_FIXED as a fallback only when the hint-only attempt doesn't land at the requested address, so the safer hint path is still tried first.
This commit is contained in:
@@ -271,6 +271,26 @@ internal sealed unsafe class PosixHostMemory : IHostMemory
|
||||
|
||||
var exactFlags = OperatingSystem.IsMacOS() ? flags : flags | MAP_FIXED_NOREPLACE;
|
||||
result = mmap((nint)address, (nuint)alignedSize, posixProtect, exactFlags, -1, 0);
|
||||
if (result != MAP_FAILED && (ulong)result != (ulong)address)
|
||||
{
|
||||
munmap(result, (nuint)alignedSize);
|
||||
result = MAP_FAILED;
|
||||
}
|
||||
|
||||
if (result == MAP_FAILED && OperatingSystem.IsMacOS())
|
||||
{
|
||||
// The hint-only attempt above didn't land at the requested
|
||||
// address. This is routinely the case for the PS5's fixed
|
||||
// 32 GiB image base under Rosetta 2 on Apple Silicon, where
|
||||
// the kernel never honors that hint. Retry with true
|
||||
// MAP_FIXED: this can clobber an untracked host mapping
|
||||
// (dyld, the runtime's JIT heap, Rosetta) if one already
|
||||
// sits exactly there, but without it guest images that
|
||||
// require this base never load at all on macOS.
|
||||
Trace($"exact mmap hint failed, retrying with MAP_FIXED: addr=0x{(ulong)address:X16}");
|
||||
result = mmap((nint)address, (nuint)alignedSize, posixProtect, flags | MAP_FIXED, -1, 0);
|
||||
}
|
||||
|
||||
if (result == MAP_FAILED || (ulong)result != (ulong)address)
|
||||
{
|
||||
Trace($"exact mmap failed: addr=0x{(ulong)address:X16} got=0x{(ulong)result:X16} size=0x{alignedSize:X} errno={Marshal.GetLastPInvokeError()}");
|
||||
|
||||
Reference in New Issue
Block a user