From 1c0617146c2a1e8f2cd8a48061f6d53ffc412822 Mon Sep 17 00:00:00 2001 From: AlpinDale Date: Tue, 9 Dec 2025 00:33:28 +0430 Subject: [PATCH] flexible address in mmap --- src/core/address_space.cpp | 63 +++++++++++++++----------------------- 1 file changed, 24 insertions(+), 39 deletions(-) diff --git a/src/core/address_space.cpp b/src/core/address_space.cpp index bb20ad659..5327d6fa0 100644 --- a/src/core/address_space.cpp +++ b/src/core/address_space.cpp @@ -532,56 +532,41 @@ struct AddressSpace::Impl { user_base = reinterpret_cast( mmap(reinterpret_cast(USER_MIN), user_size, protection_flags, map_flags, -1, 0)); #elif defined(ARCH_ARM64) - // On ARM64 macOS, MAP_FIXED may not work at these addresses due to system restrictions. - // We need these exact addresses for the PS4 memory layout, so we try multiple approaches. - int map_flags_fixed = MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE | MAP_FIXED; + // On ARM64 macOS, MAP_FIXED doesn't work at low addresses (0x400000) due to system restrictions. + // Map memory wherever possible and use offset calculations. This is a temporary solution + // until proper address translation is implemented for ARM64. + // Note: This means the PS4 virtual addresses won't match host addresses, so instruction + // translation/JIT will need to handle the offset. + constexpr int map_flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE; + // Map the three regions separately, but let the system choose addresses system_managed_base = - reinterpret_cast(mmap(reinterpret_cast(SYSTEM_MANAGED_MIN), - system_managed_size, protection_flags, map_flags_fixed, -1, 0)); + reinterpret_cast(mmap(nullptr, system_managed_size, protection_flags, map_flags, -1, 0)); if (system_managed_base == MAP_FAILED) { - // Try without MAP_NORESERVE - int map_flags_noreserve = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED; - system_managed_base = - reinterpret_cast(mmap(reinterpret_cast(SYSTEM_MANAGED_MIN), - system_managed_size, protection_flags, map_flags_noreserve, -1, 0)); - if (system_managed_base == MAP_FAILED) { - LOG_CRITICAL(Kernel_Vmm, "mmap failed for system_managed_base at {}: {}. " - "ARM64 macOS does not allow mapping at address 0x400000. " - "The PS4 memory layout requires exact addresses. " - "Consider using x86_64 mode or implementing address translation for ARM64.", - fmt::ptr(reinterpret_cast(SYSTEM_MANAGED_MIN)), strerror(errno)); - throw std::bad_alloc{}; - } + LOG_CRITICAL(Kernel_Vmm, "mmap failed for system_managed_base: {}", strerror(errno)); + throw std::bad_alloc{}; } system_reserved_base = - reinterpret_cast(mmap(reinterpret_cast(SYSTEM_RESERVED_MIN), - system_reserved_size, protection_flags, map_flags_fixed, -1, 0)); + reinterpret_cast(mmap(nullptr, system_reserved_size, protection_flags, map_flags, -1, 0)); if (system_reserved_base == MAP_FAILED) { - int map_flags_noreserve = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED; - system_reserved_base = - reinterpret_cast(mmap(reinterpret_cast(SYSTEM_RESERVED_MIN), - system_reserved_size, protection_flags, map_flags_noreserve, -1, 0)); - if (system_reserved_base == MAP_FAILED) { - LOG_CRITICAL(Kernel_Vmm, "mmap failed for system_reserved_base at {}: {}", - fmt::ptr(reinterpret_cast(SYSTEM_RESERVED_MIN)), strerror(errno)); - throw std::bad_alloc{}; - } + LOG_CRITICAL(Kernel_Vmm, "mmap failed for system_reserved_base: {}", strerror(errno)); + throw std::bad_alloc{}; } user_base = reinterpret_cast( - mmap(reinterpret_cast(USER_MIN), user_size, protection_flags, map_flags_fixed, -1, 0)); + mmap(nullptr, user_size, protection_flags, map_flags, -1, 0)); if (user_base == MAP_FAILED) { - int map_flags_noreserve = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED; - user_base = reinterpret_cast( - mmap(reinterpret_cast(USER_MIN), user_size, protection_flags, map_flags_noreserve, -1, 0)); - if (user_base == MAP_FAILED) { - LOG_CRITICAL(Kernel_Vmm, "mmap failed for user_base at {}: {}", - fmt::ptr(reinterpret_cast(USER_MIN)), strerror(errno)); - throw std::bad_alloc{}; - } + LOG_CRITICAL(Kernel_Vmm, "mmap failed for user_base: {}", strerror(errno)); + throw std::bad_alloc{}; } + + LOG_WARNING(Kernel_Vmm, "ARM64 macOS: Using flexible memory layout. " + "PS4 addresses will be offset from host addresses. " + "system_managed: {} (expected {}), system_reserved: {} (expected {}), user: {} (expected {})", + fmt::ptr(system_managed_base), fmt::ptr(reinterpret_cast(SYSTEM_MANAGED_MIN)), + fmt::ptr(system_reserved_base), fmt::ptr(reinterpret_cast(SYSTEM_RESERVED_MIN)), + fmt::ptr(user_base), fmt::ptr(reinterpret_cast(USER_MIN))); #endif #else const auto virtual_size = system_managed_size + system_reserved_size + user_size; @@ -618,7 +603,7 @@ struct AddressSpace::Impl { fmt::ptr(user_base + user_size - 1)); const VAddr system_managed_addr = reinterpret_cast(system_managed_base); - const VAddr system_reserved_addr = reinterpret_cast(system_managed_base); + const VAddr system_reserved_addr = reinterpret_cast(system_reserved_base); const VAddr user_addr = reinterpret_cast(user_base); m_free_regions.insert({system_managed_addr, system_managed_addr + system_managed_size}); m_free_regions.insert({system_reserved_addr, system_reserved_addr + system_reserved_size});