System: Add advanced 'Export Shared Memory' option

Memory map is exported as duckstation_<pid>. Previously, this only
worked on Windows, now it is extended to Linux as well.
This commit is contained in:
Stenzek
2024-08-04 20:00:33 +10:00
parent c538df317a
commit 02fbfae6a0
12 changed files with 187 additions and 55 deletions

View File

@ -66,9 +66,10 @@ std::string MemMap::GetFileMappingName(const char* prefix)
void* MemMap::CreateSharedMemory(const char* name, size_t size, Error* error)
{
const std::wstring mapping_name = name ? StringUtil::UTF8StringToWideString(name) : std::wstring();
const HANDLE mapping =
CreateFileMappingW(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE, static_cast<DWORD>(size >> 32),
static_cast<DWORD>(size), StringUtil::UTF8StringToWideString(name).c_str());
static_cast<DWORD>(size), mapping_name.empty() ? nullptr : mapping_name.c_str());
if (!mapping)
Error::SetWin32(error, "CreateFileMappingW() failed: ", GetLastError());
@ -80,6 +81,11 @@ void MemMap::DestroySharedMemory(void* ptr)
CloseHandle(static_cast<HANDLE>(ptr));
}
void MemMap::DeleteSharedMemory(const char* name)
{
// Automatically freed on close.
}
void* MemMap::MapSharedMemory(void* handle, size_t offset, void* baseaddr, size_t size, PageProtect mode)
{
void* ret = MapViewOfFileEx(static_cast<HANDLE>(handle), FILE_MAP_READ | FILE_MAP_WRITE,
@ -374,6 +380,10 @@ void MemMap::DestroySharedMemory(void* ptr)
mach_port_deallocate(mach_task_self(), static_cast<mach_port_t>(reinterpret_cast<uintptr_t>(ptr)));
}
void MemMap::DeleteSharedMemory(const char* name)
{
}
void* MemMap::MapSharedMemory(void* handle, size_t offset, void* baseaddr, size_t size, PageProtect mode)
{
mach_vm_address_t ptr = reinterpret_cast<mach_vm_address_t>(baseaddr);
@ -617,15 +627,25 @@ std::string MemMap::GetFileMappingName(const char* prefix)
void* MemMap::CreateSharedMemory(const char* name, size_t size, Error* error)
{
const bool is_anonymous = (!name || *name == 0);
#if defined(__linux__) || defined(__FreeBSD__)
const int fd = is_anonymous ? memfd_create("", 0) : shm_open(name, O_CREAT | O_EXCL | O_RDWR, 0600);
if (fd < 0)
{
Error::SetErrno(error, is_anonymous ? "memfd_create() failed: " : "shm_open() failed: ", errno);
return nullptr;
}
#else
const int fd = shm_open(name, O_CREAT | O_EXCL | O_RDWR, 0600);
if (fd < 0)
{
Error::SetErrno(error, "shm_open failed: ", errno);
Error::SetErrno(error, "shm_open() failed: ", errno);
return nullptr;
}
// we're not going to be opening this mapping in other processes, so remove the file
shm_unlink(name);
#endif
// use fallocate() to ensure we don't SIGBUS later on.
#ifdef __linux__
@ -651,6 +671,11 @@ void MemMap::DestroySharedMemory(void* ptr)
close(static_cast<int>(reinterpret_cast<intptr_t>(ptr)));
}
void MemMap::DeleteSharedMemory(const char* name)
{
shm_unlink(name);
}
void* MemMap::MapSharedMemory(void* handle, size_t offset, void* baseaddr, size_t size, PageProtect mode)
{
const int flags = (baseaddr != nullptr) ? (MAP_SHARED | MAP_FIXED) : MAP_SHARED;