JitCache: Fix potentially dangling pointer to fast block map.

Whenever JitBaseBlockCache::Clear() got called, it threw away the memory mapping for the fast block map and created a new one. This new mapping typically got mapped at the same address at the old one, but this is not guaranteed. The pointer to the mapping gets embedded in the generated dispatcher code in Jit64AsmRoutineManager::Generate(), which is only called once on game boot, so if the new mapping ended up at a different address than the old one, the pointer in the ASM pointed at garbage, leading to a crash.

This fixes the issue by guaranteeing that the new mapping is mapped at the same address.
This commit is contained in:
Admiral H. Curtiss 2023-09-02 04:03:15 +02:00
parent 5bd7756064
commit f1c1c6ded6
No known key found for this signature in database
GPG Key ID: F051B4C4044F33FB
2 changed files with 8 additions and 25 deletions

View File

@ -42,7 +42,11 @@ void JitBaseBlockCache::Init()
{
Common::JitRegister::Init(Config::Get(Config::MAIN_PERF_MAP_DIR));
m_block_map_arena.GrabSHMSegment(FAST_BLOCK_MAP_SIZE, "dolphin-emu-jitblock");
m_fast_block_map = reinterpret_cast<JitBlock**>(m_block_map_arena.Create(FAST_BLOCK_MAP_SIZE));
if (m_fast_block_map)
m_fast_block_map_ptr = m_fast_block_map;
else
m_fast_block_map_ptr = m_fast_block_map_fallback.data();
Clear();
}
@ -51,12 +55,7 @@ void JitBaseBlockCache::Shutdown()
{
Common::JitRegister::Shutdown();
if (m_fast_block_map)
{
m_block_map_arena.ReleaseView(m_fast_block_map, FAST_BLOCK_MAP_SIZE);
}
m_block_map_arena.ReleaseSHMSegment();
m_block_map_arena.Release();
}
// This clears the JIT cache. It's called from JitCache.cpp when the JIT cache
@ -80,23 +79,7 @@ void JitBaseBlockCache::Clear()
valid_block.ClearAll();
if (m_fast_block_map)
{
m_block_map_arena.ReleaseView(m_fast_block_map, FAST_BLOCK_MAP_SIZE);
m_block_map_arena.ReleaseSHMSegment();
m_block_map_arena.GrabSHMSegment(FAST_BLOCK_MAP_SIZE, "dolphin-emu-jitblock");
}
m_fast_block_map =
reinterpret_cast<JitBlock**>(m_block_map_arena.CreateView(0, FAST_BLOCK_MAP_SIZE));
if (m_fast_block_map)
{
m_fast_block_map_ptr = m_fast_block_map;
}
else
{
m_fast_block_map_ptr = m_fast_block_map_fallback.data();
}
m_block_map_arena.Clear();
}
void JitBaseBlockCache::Reset()

View File

@ -212,7 +212,7 @@ private:
// This is used as a fast cache of block_map used in the assembly dispatcher.
// It is implemented via a shm segment using m_block_map_arena.
JitBlock** m_fast_block_map = 0;
Common::MemArena m_block_map_arena;
Common::LazyMemoryRegion m_block_map_arena;
// An alternative for the above fast_block_map but without a shm segment
// in case the shm memory region couldn't be allocated.