diff --git a/Common/Arm64Emitter.cpp b/Common/Arm64Emitter.cpp index 5dd3b4d07e..17771d19cc 100644 --- a/Common/Arm64Emitter.cpp +++ b/Common/Arm64Emitter.cpp @@ -302,7 +302,7 @@ const u8* ARM64XEmitter::AlignCode16() { int c = int((u64)m_code & 15); if (c) - ReserveCodeSpace(16-c); + ReserveCodeSpace(16 - c); return m_code; } @@ -509,7 +509,7 @@ void ARM64XEmitter::EncodeTestBranchInst(u32 op, ARM64Reg Rt, u8 bits, const voi distance >>= 2; - _assert_msg_(DYNA_REC, distance >= -0x3FFF && distance < 0x3FFF, "%s: Received too large distance: %llx", __FUNCTION__, distance); + _assert_msg_(DYNA_REC, distance >= -0x1FFF && distance < 0x1FFF, "%s: Received too large distance: %llx", __FUNCTION__, distance); Rt = DecodeReg(Rt); Write32((b64Bit << 31) | (0x36 << 24) | (op << 24) | \ @@ -3896,4 +3896,15 @@ void ARM64XEmitter::SUBSI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch) } } +void ARM64CodeBlock::PoisonMemory(int offset) { + u32* ptr = (u32*)(region + offset); + u32* maxptr = (u32*)(region + region_size - offset); + // If our memory isn't a multiple of u32 then this won't write the last remaining bytes with anything + // Less than optimal, but there would be nothing we could do but throw a runtime warning anyway. + // AArch64: 0xD4200000 = BRK 0 + while (ptr < maxptr) + *ptr++ = 0xD4200000; + FlushIcacheSection((u8 *)ptr, (u8 *)maxptr); +} + } // namespace diff --git a/Common/Arm64Emitter.h b/Common/Arm64Emitter.h index 1b65e69d66..4a05b9564b 100644 --- a/Common/Arm64Emitter.h +++ b/Common/Arm64Emitter.h @@ -985,15 +985,6 @@ private: class ARM64CodeBlock : public CodeBlock { private: - void PoisonMemory() override - { - u32* ptr = (u32*)region; - u32* maxptr = (u32*)(region + region_size); - // If our memory isn't a multiple of u32 then this won't write the last remaining bytes with anything - // Less than optimal, but there would be nothing we could do but throw a runtime warning anyway. - // AArch64: 0xD4200000 = BRK 0 - while (ptr < maxptr) - *ptr++ = 0xD4200000; - } + void PoisonMemory(int offset) override; }; } diff --git a/Common/ArmEmitter.cpp b/Common/ArmEmitter.cpp index 8f11037260..1321bf28be 100644 --- a/Common/ArmEmitter.cpp +++ b/Common/ArmEmitter.cpp @@ -3211,10 +3211,10 @@ void ARMXEmitter::VCVTF16F32(ARMReg Dest, ARMReg Src) { // Always clear code space with breakpoints, so that if someone accidentally executes // uninitialized, it just breaks into the debugger. -void ARMXCodeBlock::PoisonMemory() { +void ARMXCodeBlock::PoisonMemory(int offset) { // TODO: this isn't right for ARM! - memset(region, 0xCC, region_size); - ResetCodePtr(); + memset(region + offset, 0xCC, region_size - offset); + ResetCodePtr(offset); } } diff --git a/Common/ArmEmitter.h b/Common/ArmEmitter.h index 1b77020355..85c2d916b7 100644 --- a/Common/ArmEmitter.h +++ b/Common/ArmEmitter.h @@ -895,7 +895,7 @@ public: class ARMXCodeBlock : public CodeBlock { public: - void PoisonMemory() override; + void PoisonMemory(int offset) override; }; // VFP Specific diff --git a/Common/CodeBlock.h b/Common/CodeBlock.h index a9911fcdd5..9887385548 100644 --- a/Common/CodeBlock.h +++ b/Common/CodeBlock.h @@ -42,7 +42,7 @@ template class CodeBlock : public CodeBlockCommon, public T, NonCopyabl private: // A privately used function to set the executable RAM space to something invalid. // For debugging usefulness it should be used to set the RAM to a host specific breakpoint instruction - virtual void PoisonMemory() = 0; + virtual void PoisonMemory(int offset) = 0; public: CodeBlock() : writeStart_(nullptr) {} @@ -58,14 +58,13 @@ public: // Always clear code space with breakpoints, so that if someone accidentally executes // uninitialized, it just breaks into the debugger. - void ClearCodeSpace() { + void ClearCodeSpace(int offset) { if (PlatformIsWXExclusive()) { ProtectMemoryPages(region, region_size, MEM_PROT_READ | MEM_PROT_WRITE); - } else { - ProtectMemoryPages(region, region_size, MEM_PROT_READ | MEM_PROT_WRITE | MEM_PROT_EXEC); } - PoisonMemory(); - ResetCodePtr(); + // If not WX Exclusive, no need to call ProtectMemoryPages because we never change the protection from RWX. + PoisonMemory(offset); + ResetCodePtr(offset); } // BeginWrite/EndWrite assume that we keep appending. @@ -109,8 +108,8 @@ public: return T::GetCodePointer(); } - void ResetCodePtr() { - T::SetCodePointer(region); + void ResetCodePtr(int offset) { + T::SetCodePointer(region + offset); } size_t GetSpaceLeft() const { diff --git a/Common/MemoryUtil.cpp b/Common/MemoryUtil.cpp index d1c41c85cd..db63c68c9a 100644 --- a/Common/MemoryUtil.cpp +++ b/Common/MemoryUtil.cpp @@ -17,6 +17,8 @@ #include "ppsspp_config.h" +#include "base/logging.h" + #include "Common.h" #include "MemoryUtil.h" #include "StringUtils.h" diff --git a/Common/Thunk.cpp b/Common/Thunk.cpp index 401ffd6212..8b770a8109 100644 --- a/Common/Thunk.cpp +++ b/Common/Thunk.cpp @@ -101,7 +101,7 @@ void ThunkManager::Init() void ThunkManager::Reset() { thunks.clear(); - ResetCodePtr(); + ResetCodePtr(0); } void ThunkManager::Shutdown() diff --git a/Common/x64Emitter.cpp b/Common/x64Emitter.cpp index 0b48c928b9..3d9b9c4e81 100644 --- a/Common/x64Emitter.cpp +++ b/Common/x64Emitter.cpp @@ -1980,9 +1980,9 @@ void XEmitter::FNSTSW_AX() { Write8(0xDF); Write8(0xE0); } void XEmitter::RDTSC() { Write8(0x0F); Write8(0x31); } -void XCodeBlock::PoisonMemory() { +void XCodeBlock::PoisonMemory(int offset) { // x86/64: 0xCC = breakpoint - memset(region, 0xCC, region_size); + memset(region + offset, 0xCC, region_size - offset); } } diff --git a/Common/x64Emitter.h b/Common/x64Emitter.h index 38dfe9c586..bcfc592bdd 100644 --- a/Common/x64Emitter.h +++ b/Common/x64Emitter.h @@ -1061,7 +1061,7 @@ public: class XCodeBlock : public CodeBlock { public: - void PoisonMemory() override; + void PoisonMemory(int offset) override; }; } // namespace diff --git a/Core/MIPS/ARM/ArmJit.cpp b/Core/MIPS/ARM/ArmJit.cpp index cdd19dbc70..507238f459 100644 --- a/Core/MIPS/ARM/ArmJit.cpp +++ b/Core/MIPS/ARM/ArmJit.cpp @@ -152,7 +152,7 @@ void ArmJit::FlushPrefixV() void ArmJit::ClearCache() { blocks.Clear(); - ClearCodeSpace(); + ClearCodeSpace(0); GenerateFixedCode(); } diff --git a/Core/MIPS/ARM64/Arm64Asm.cpp b/Core/MIPS/ARM64/Arm64Asm.cpp index 4a37a8da22..b3b69e623e 100644 --- a/Core/MIPS/ARM64/Arm64Asm.cpp +++ b/Core/MIPS/ARM64/Arm64Asm.cpp @@ -318,10 +318,11 @@ void Arm64Jit::GenerateFixedCode(const JitOptions &jo) { } } - // Don't forget to zap the instruction cache! This must stay at the end of this function. - FlushIcache(); // Let's spare the pre-generated code from unprotect-reprotect. AlignCodePage(); + jitStartOffset = (int)(GetCodePtr() - start); + // Don't forget to zap the instruction cache! This must stay at the end of this function. + FlushIcache(); EndWrite(); } diff --git a/Core/MIPS/ARM64/Arm64Jit.cpp b/Core/MIPS/ARM64/Arm64Jit.cpp index 13971cb6b6..fab227f303 100644 --- a/Core/MIPS/ARM64/Arm64Jit.cpp +++ b/Core/MIPS/ARM64/Arm64Jit.cpp @@ -142,8 +142,7 @@ void Arm64Jit::FlushPrefixV() { void Arm64Jit::ClearCache() { ILOG("ARM64Jit: Clearing the cache!"); blocks.Clear(); - ClearCodeSpace(); - GenerateFixedCode(jo); + ClearCodeSpace(jitStartOffset); } void Arm64Jit::InvalidateCacheAt(u32 em_address, int length) { diff --git a/Core/MIPS/ARM64/Arm64Jit.h b/Core/MIPS/ARM64/Arm64Jit.h index 2eed09ee0c..b2d853c3b2 100644 --- a/Core/MIPS/ARM64/Arm64Jit.h +++ b/Core/MIPS/ARM64/Arm64Jit.h @@ -280,6 +280,8 @@ public: const u8 *applyRoundingMode; const u8 *updateRoundingMode; + int jitStartOffset; + // Indexed by FPCR FZ:RN bits for convenience. Uses SCRATCH2. const u8 *convertS0ToSCRATCH1[8]; }; diff --git a/Core/MIPS/x86/Jit.cpp b/Core/MIPS/x86/Jit.cpp index 1d769ab277..431b4ed5bb 100644 --- a/Core/MIPS/x86/Jit.cpp +++ b/Core/MIPS/x86/Jit.cpp @@ -219,7 +219,7 @@ void Jit::UpdateRoundingMode() { void Jit::ClearCache() { blocks.Clear(); - ClearCodeSpace(); + ClearCodeSpace(0); GenerateFixedCode(jo); } diff --git a/Core/MIPS/x86/JitSafeMem.cpp b/Core/MIPS/x86/JitSafeMem.cpp index fb3aeaa5d4..a135182dfe 100644 --- a/Core/MIPS/x86/JitSafeMem.cpp +++ b/Core/MIPS/x86/JitSafeMem.cpp @@ -448,7 +448,7 @@ void JitSafeMemFuncs::Init(ThunkManager *thunks) { } void JitSafeMemFuncs::Shutdown() { - ResetCodePtr(); + ResetCodePtr(0); FreeCodeSpace(); } diff --git a/GPU/Common/VertexDecoderCommon.cpp b/GPU/Common/VertexDecoderCommon.cpp index 63f33f845c..53b1313144 100644 --- a/GPU/Common/VertexDecoderCommon.cpp +++ b/GPU/Common/VertexDecoderCommon.cpp @@ -1281,5 +1281,5 @@ VertexDecoderJitCache::VertexDecoderJitCache() } void VertexDecoderJitCache::Clear() { - ClearCodeSpace(); + ClearCodeSpace(0); }