Merge pull request #10049 from JosJuice/jitarm64-fault-to-handler
JitArm64: Make HandleFastmemFault less unsafe
This commit is contained in:
commit
922f53e16e
|
@ -195,7 +195,7 @@ protected:
|
||||||
|
|
||||||
struct FastmemArea
|
struct FastmemArea
|
||||||
{
|
{
|
||||||
u32 length;
|
const u8* fastmem_code;
|
||||||
const u8* slowmem_code;
|
const u8* slowmem_code;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -134,7 +134,7 @@ void JitArm64::EmitBackpatchRoutine(u32 flags, bool fastmem, bool do_farcode, AR
|
||||||
handler.fprs = fprs_to_push;
|
handler.fprs = fprs_to_push;
|
||||||
handler.flags = flags;
|
handler.flags = flags;
|
||||||
|
|
||||||
FastmemArea* fastmem_area = &m_fault_to_handler[fastmem_start];
|
FastmemArea* fastmem_area = &m_fault_to_handler[fastmem_end];
|
||||||
auto handler_loc_iter = m_handler_to_loc.find(handler);
|
auto handler_loc_iter = m_handler_to_loc.find(handler);
|
||||||
|
|
||||||
if (handler_loc_iter == m_handler_to_loc.end())
|
if (handler_loc_iter == m_handler_to_loc.end())
|
||||||
|
@ -143,14 +143,14 @@ void JitArm64::EmitBackpatchRoutine(u32 flags, bool fastmem, bool do_farcode, AR
|
||||||
SwitchToFarCode();
|
SwitchToFarCode();
|
||||||
const u8* handler_loc = GetCodePtr();
|
const u8* handler_loc = GetCodePtr();
|
||||||
m_handler_to_loc[handler] = handler_loc;
|
m_handler_to_loc[handler] = handler_loc;
|
||||||
|
fastmem_area->fastmem_code = fastmem_start;
|
||||||
fastmem_area->slowmem_code = handler_loc;
|
fastmem_area->slowmem_code = handler_loc;
|
||||||
fastmem_area->length = fastmem_end - fastmem_start;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const u8* handler_loc = handler_loc_iter->second;
|
const u8* handler_loc = handler_loc_iter->second;
|
||||||
|
fastmem_area->fastmem_code = fastmem_start;
|
||||||
fastmem_area->slowmem_code = handler_loc;
|
fastmem_area->slowmem_code = handler_loc;
|
||||||
fastmem_area->length = fastmem_end - fastmem_start;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -253,33 +253,32 @@ bool JitArm64::HandleFastmemFault(uintptr_t access_address, SContext* ctx)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto slow_handler_iter = m_fault_to_handler.upper_bound((const u8*)ctx->CTX_PC);
|
const u8* pc = reinterpret_cast<const u8*>(ctx->CTX_PC);
|
||||||
slow_handler_iter--;
|
auto slow_handler_iter = m_fault_to_handler.upper_bound(pc);
|
||||||
|
|
||||||
// no fastmem area found
|
// no fastmem area found
|
||||||
if (slow_handler_iter == m_fault_to_handler.end())
|
if (slow_handler_iter == m_fault_to_handler.end())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const u8* fault_location = slow_handler_iter->first;
|
const u8* fastmem_area_start = slow_handler_iter->second.fastmem_code;
|
||||||
const u32 fastmem_area_length = slow_handler_iter->second.length;
|
const u8* fastmem_area_end = slow_handler_iter->first;
|
||||||
|
|
||||||
// no overlapping fastmem area found
|
// no overlapping fastmem area found
|
||||||
if ((const u8*)ctx->CTX_PC - fault_location > fastmem_area_length)
|
if (pc < fastmem_area_start)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const Common::ScopedJITPageWriteAndNoExecute enable_jit_page_writes;
|
const Common::ScopedJITPageWriteAndNoExecute enable_jit_page_writes;
|
||||||
ARM64XEmitter emitter((u8*)fault_location);
|
ARM64XEmitter emitter(const_cast<u8*>(fastmem_area_start));
|
||||||
|
|
||||||
emitter.BL(slow_handler_iter->second.slowmem_code);
|
emitter.BL(slow_handler_iter->second.slowmem_code);
|
||||||
|
|
||||||
const u32 num_insts_max = fastmem_area_length / 4 - 1;
|
while (emitter.GetCodePtr() < fastmem_area_end)
|
||||||
for (u32 i = 0; i < num_insts_max; ++i)
|
|
||||||
emitter.NOP();
|
emitter.NOP();
|
||||||
|
|
||||||
m_fault_to_handler.erase(slow_handler_iter);
|
m_fault_to_handler.erase(slow_handler_iter);
|
||||||
|
|
||||||
emitter.FlushIcache();
|
emitter.FlushIcache();
|
||||||
|
|
||||||
ctx->CTX_PC = reinterpret_cast<std::uintptr_t>(fault_location);
|
ctx->CTX_PC = reinterpret_cast<std::uintptr_t>(fastmem_area_start);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue