mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
arm64jit: Don't sign-extend constant addresses with the top bit set
The ARM64 IR JIT crashed on any load/store to a constant address with the top bit set and an offset too large for an immediate - the kernel RAM mirror at 0x88000000, for instance. PrepareSrc1Address is careful about this: a constant address like 0x89100010 arrives sign-extended as a negative int64_t, and the (imm & 0xC0000000) == 0x80000000 check turns it back into the positive value it should be. But when the offset doesn't fit an immediate we fall back to loading it into a register and using the register-offset addressing mode, which only takes the W half of that register plus an extend - and we asked for SXTW, undoing the fix and pointing the access ~2GB below the memory view. Sign extension is still right when the offset is genuinely negative, which happens when the base is a pointerified register and the displacement is a negative one from the MIPS instruction. So extend based on the sign of imm. Found by the Jit unit test, which stores to 0x89100000 and segfaults in the JIT_IR phase - only reproducible on an actual ARM64 CPU, which is why it never showed up on CI. The RISC-V and LoongArch backends get this case right already.
This commit is contained in:
1 parent
c34f5000ab
commit
3ef6ad6285
1 file changed
+6
-1
@@ -153,7 +153,12 @@ Arm64JitBackend::LoadStoreArg Arm64JitBackend::PrepareSrc1Address(IRInst inst) {
|
||||
MOVI2R(SCRATCH1, imm);
|
||||
addrArg.regOffset = SCRATCH1;
|
||||
addrArg.useRegisterOffset = true;
|
||||
addrArg.signExtendRegOffset = true;
|
||||
// Careful: the register offset is only the W half, extended into the 64-bit base.
|
||||
// A negative imm here is a real displacement from a pointerified register, so it
|
||||
// has to be sign extended. A positive one may be a full 32-bit address off
|
||||
// MEMBASEREG with the top bit set, which we un-sign-extended above - SXTW would
|
||||
// just make it negative again and point us ~2GB below the memory view.
|
||||
addrArg.signExtendRegOffset = imm < 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user