mirror of
https://github.com/ARMSX2/ARMSX2.git
synced 2026-08-24 16:50:16 -07:00
iOS: Use sandbox-safe shared memory for GS
GSAllocateWrappedMemory's POSIX branch called shm_open("/GS.mem",
O_RDWR | O_CREAT | O_EXCL, 0600) directly. The iOS application
sandbox rejects named POSIX shared memory in the system-wide
namespace, so shm_open returned -1, the function returned nullptr,
and GSLocalMemory::GSLocalMemory() aborted via
pxFailRel("Failed to allocate GS memory storage."). On hosts that
re-enter the CPU thread across launches, this surfaced as a game-
launch abort on the GS thread.
The rest of the codebase already routes shared-memory creation
through HostSys::CreateSharedMemory (pcsx2/Memory.cpp uses it for
EE/IOP RAM), whose Linux/Apple branch selects memfd_create on
Android, shm_open on desktop POSIX, and a file-backed TMPDIR
fallback on iOS so the same call works under the sandbox.
GSAllocateWrappedMemory was the only production caller bypassing
the helper.
Delegate fd creation to HostSys::CreateSharedMemory, drop the
Android-only memfd_create special-case and the redundant ftruncate
(both are handled inside the helper), and use
HostSys::GetFileMappingName so the name is PID-qualified instead of
the fixed "/GS.mem". The MAP_SHARED repeat-mirroring mmap loop is
preserved unchanged so the 4 MB GS VRAM still appears `repeat` times
at contiguous virtual addresses for the PS2 GS address-wrap
behaviour. GSFreeWrappedMemory is updated symmetrically to call
HostSys::DestroySharedMemory.
The Windows branch is untouched, and the caller contract (return
nullptr on failure; the caller's pxFailRel handles the abort) is
preserved.
Verified with the iOS build and repeated game launch/exit/relaunch
cycles: GSLocalMemory construction no longer aborts and the wrapped
memory layout is unchanged.
This commit is contained in:
+15
-25
@@ -44,6 +44,7 @@
|
||||
|
||||
#include "common/Console.h"
|
||||
#include "common/FileSystem.h"
|
||||
#include "common/HostSys.h"
|
||||
#include "common/Path.h"
|
||||
#include "common/SmallString.h"
|
||||
#include "common/StringUtil.h"
|
||||
@@ -1079,10 +1080,6 @@ void GSFreeWrappedMemory(void* ptr, size_t size, size_t repeat)
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#if defined(__ANDROID__)
|
||||
#include <sys/syscall.h>
|
||||
#include <android/sharedmem.h>
|
||||
#endif
|
||||
|
||||
static int s_shm_fd = -1;
|
||||
|
||||
@@ -1090,29 +1087,22 @@ void* GSAllocateWrappedMemory(size_t size, size_t repeat)
|
||||
{
|
||||
pxAssert(s_shm_fd == -1);
|
||||
|
||||
const char* file_name = "/GS.mem";
|
||||
#if defined(__ANDROID__)
|
||||
s_shm_fd = static_cast<int>(syscall(__NR_memfd_create, "GS.mem", 0));
|
||||
if (s_shm_fd == -1)
|
||||
// Route fd creation through HostSys::CreateSharedMemory so iOS gets the
|
||||
// file-backed fallback the helper already provides for the rest of the
|
||||
// codebase. The bare shm_open("/GS.mem", ...) the prior implementation
|
||||
// used is rejected by the iOS sandbox, which returned -1 and propagated
|
||||
// nullptr up to GSLocalMemory.
|
||||
const std::string file_name = HostSys::GetFileMappingName("GS.mem");
|
||||
void* const handle = HostSys::CreateSharedMemory(file_name.c_str(), repeat * size);
|
||||
if (!handle)
|
||||
{
|
||||
fprintf(stderr, "Failed to create memfd due to %s\n", strerror(errno));
|
||||
std::fprintf(stderr,
|
||||
"GSAllocateWrappedMemory: HostSys::CreateSharedMemory failed "
|
||||
"(size=%zu repeat=%zu total=%zu)\n",
|
||||
size, repeat, repeat * size);
|
||||
return nullptr;
|
||||
}
|
||||
#else
|
||||
s_shm_fd = shm_open(file_name, O_RDWR | O_CREAT | O_EXCL, 0600);
|
||||
if (s_shm_fd != -1)
|
||||
{
|
||||
shm_unlink(file_name); // file is deleted but descriptor is still open
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "Failed to open %s due to %s\n", file_name, strerror(errno));
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ftruncate(s_shm_fd, repeat * size) < 0)
|
||||
fprintf(stderr, "Failed to reserve memory due to %s\n", strerror(errno));
|
||||
s_shm_fd = static_cast<int>(reinterpret_cast<intptr_t>(handle));
|
||||
|
||||
void* fifo = mmap(nullptr, size * repeat, PROT_READ | PROT_WRITE, MAP_SHARED, s_shm_fd, 0);
|
||||
|
||||
@@ -1136,7 +1126,7 @@ void GSFreeWrappedMemory(void* ptr, size_t size, size_t repeat)
|
||||
|
||||
munmap(ptr, size * repeat);
|
||||
|
||||
close(s_shm_fd);
|
||||
HostSys::DestroySharedMemory(reinterpret_cast<void*>(static_cast<intptr_t>(s_shm_fd)));
|
||||
s_shm_fd = -1;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user