Fix arm64 MOVI2R for addresses between 2gb and 4gb offset from PC

The PC offset ADRP() path takes a s32 value, but the input offset was
being tested as abs(ptr) < 0xFFFFFFFF. This caused values between
0x80000000 and 0xFFFFFFFF to incorrectly use this path, despite the
offsets not being representable in an s32.

This caused a crash in the VertexLoader on android 8.1 immediate in wind
waker (and possibly all other apps on android 8.1) as the jit and data
sections happened to be loaded 4gb apart in virtual memory, causing some
pointers to hit this
This commit is contained in:
Jonathan Hamilton 2017-12-09 13:14:38 -08:00
parent 1a9d6b99e9
commit 8ae76a6680

View File

@ -2029,7 +2029,8 @@ void ARM64XEmitter::MOVI2R(ARM64Reg Rd, u64 imm, bool optimize)
u64 aligned_pc = (u64)GetCodePtr() & ~0xFFF;
s64 aligned_offset = (s64)imm - (s64)aligned_pc;
if (upload_part.Count() > 1 && std::abs(aligned_offset) < 0xFFFFFFFFLL)
// The offset for ADR/ADRP is an s32, so make sure it can be represented in that
if (upload_part.Count() > 1 && std::abs(aligned_offset) < 0x7FFFFFFFLL)
{
// Immediate we are loading is within 4GB of our aligned range
// Most likely a address that we can load in one or two instructions