mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-12-16 12:09:07 +00:00
flexible address in mmap
This commit is contained in:
parent
513bc203df
commit
1c0617146c
@ -532,56 +532,41 @@ struct AddressSpace::Impl {
|
||||
user_base = reinterpret_cast<u8*>(
|
||||
mmap(reinterpret_cast<void*>(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<u8*>(mmap(reinterpret_cast<void*>(SYSTEM_MANAGED_MIN),
|
||||
system_managed_size, protection_flags, map_flags_fixed, -1, 0));
|
||||
reinterpret_cast<u8*>(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<u8*>(mmap(reinterpret_cast<void*>(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<void*>(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<u8*>(mmap(reinterpret_cast<void*>(SYSTEM_RESERVED_MIN),
|
||||
system_reserved_size, protection_flags, map_flags_fixed, -1, 0));
|
||||
reinterpret_cast<u8*>(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<u8*>(mmap(reinterpret_cast<void*>(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<void*>(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<u8*>(
|
||||
mmap(reinterpret_cast<void*>(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<u8*>(
|
||||
mmap(reinterpret_cast<void*>(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<void*>(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<void*>(SYSTEM_MANAGED_MIN)),
|
||||
fmt::ptr(system_reserved_base), fmt::ptr(reinterpret_cast<void*>(SYSTEM_RESERVED_MIN)),
|
||||
fmt::ptr(user_base), fmt::ptr(reinterpret_cast<void*>(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<VAddr>(system_managed_base);
|
||||
const VAddr system_reserved_addr = reinterpret_cast<VAddr>(system_managed_base);
|
||||
const VAddr system_reserved_addr = reinterpret_cast<VAddr>(system_reserved_base);
|
||||
const VAddr user_addr = reinterpret_cast<VAddr>(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});
|
||||
|
||||
Loading…
Reference in New Issue
Block a user