Bus: Expose shared memory on Unix systems

On Windows, the shared memory handle is closed on Destroy() and
therefore is accessible at runtime. On Unixes the shared memory was
unlinked right after its creation, effectively making the shared memory
unavailable from the outside world.
This commit brings feature parity to Unix systems.
Allows the shared memory to be accessed at runtime from an external
process for RAM inspection.
This commit is contained in:
Benjamin Mugnier 2024-05-29 18:09:13 +02:00
parent f1465ddf43
commit 793411ac59
3 changed files with 14 additions and 9 deletions

View File

@ -63,8 +63,11 @@ void* MemMap::CreateSharedMemory(const char* name, size_t size, Error* error)
return mapping;
}
void MemMap::DestroySharedMemory(void* ptr)
void MemMap::DestroySharedMemory(void* ptr, const char* name)
{
// Unused
(void)name;
CloseHandle(static_cast<HANDLE>(ptr));
}
@ -319,8 +322,11 @@ void* MemMap::CreateSharedMemory(const char* name, size_t size, Error* error)
return reinterpret_cast<void*>(static_cast<uintptr_t>(port));
}
void MemMap::DestroySharedMemory(void* ptr)
void MemMap::DestroySharedMemory(void* ptr, const char* name)
{
// Unused
(void)name;
mach_port_deallocate(mach_task_self(), static_cast<mach_port_t>(reinterpret_cast<uintptr_t>(ptr)));
}
@ -487,9 +493,6 @@ void* MemMap::CreateSharedMemory(const char* name, size_t size, Error* error)
return nullptr;
}
// we're not going to be opening this mapping in other processes, so remove the file
shm_unlink(name);
// use fallocate() to ensure we don't SIGBUS later on.
#ifdef __linux__
if (fallocate(fd, 0, 0, static_cast<off_t>(size)) < 0)
@ -509,8 +512,9 @@ void* MemMap::CreateSharedMemory(const char* name, size_t size, Error* error)
return reinterpret_cast<void*>(static_cast<intptr_t>(fd));
}
void MemMap::DestroySharedMemory(void* ptr)
void MemMap::DestroySharedMemory(void* ptr, const char* name)
{
shm_unlink(name);
close(static_cast<int>(reinterpret_cast<intptr_t>(ptr)));
}

View File

@ -53,7 +53,7 @@ class Error;
namespace MemMap {
std::string GetFileMappingName(const char* prefix);
void* CreateSharedMemory(const char* name, size_t size, Error* error);
void DestroySharedMemory(void* ptr);
void DestroySharedMemory(void* ptr, const char* name);
void* MapSharedMemory(void* handle, size_t offset, void* baseaddr, size_t size, PageProtect mode);
void UnmapSharedMemory(void* baseaddr, size_t size);
bool MemProtect(void* baseaddr, size_t size, PageProtect mode);

View File

@ -105,6 +105,7 @@ union MEMCTRL
} // namespace
static void* s_shmem_handle = nullptr;
static std::string s_shmem_name = MemMap::GetFileMappingName("duckstation");
std::bitset<RAM_8MB_CODE_PAGE_COUNT> g_ram_code_bits{};
u8* g_ram = nullptr;
@ -177,7 +178,7 @@ static constexpr size_t TOTAL_SIZE = LUT_OFFSET + LUT_SIZE;
bool Bus::AllocateMemory(Error* error)
{
s_shmem_handle =
MemMap::CreateSharedMemory(MemMap::GetFileMappingName("duckstation").c_str(), MemoryMap::TOTAL_SIZE, error);
MemMap::CreateSharedMemory(s_shmem_name.c_str(), MemoryMap::TOTAL_SIZE, error);
if (!s_shmem_handle)
{
#ifndef __linux__
@ -287,7 +288,7 @@ void Bus::ReleaseMemory()
if (s_shmem_handle)
{
MemMap::DestroySharedMemory(s_shmem_handle);
MemMap::DestroySharedMemory(s_shmem_handle, s_shmem_name.c_str());
s_shmem_handle = nullptr;
}
}