summaryrefslogtreecommitdiff
path: root/Source/Core/DiscIO/RiivolutionPatcher.cpp
diff options
context:
space:
mode:
authorScott Mansell <phiren@gmail.com>2023-02-13 16:08:36 +1300
committerGitHub <noreply@github.com>2023-02-13 16:08:36 +1300
commita4729a026f97599bbccf9f900d548fba9e391ad3 (patch)
treeeee7b79d2758d64f44aba40e627b058b3f5a9a1a /Source/Core/DiscIO/RiivolutionPatcher.cpp
parentf37113204fe8e930c4e33e5e0149fbe0309fe425 (diff)
parent6f0266e8deb9b9d46fb6f291db696fed06c1bed0 (diff)
Merge pull request #11554 from JosJuice/host-lock-cpu
DolphinQt: Properly lock CPU before accessing emulated memory
Diffstat (limited to 'Source/Core/DiscIO/RiivolutionPatcher.cpp')
-rw-r--r--Source/Core/DiscIO/RiivolutionPatcher.cpp51
1 files changed, 27 insertions, 24 deletions
diff --git a/Source/Core/DiscIO/RiivolutionPatcher.cpp b/Source/Core/DiscIO/RiivolutionPatcher.cpp
index 6469607cc1..4b265599d8 100644
--- a/Source/Core/DiscIO/RiivolutionPatcher.cpp
+++ b/Source/Core/DiscIO/RiivolutionPatcher.cpp
@@ -477,30 +477,31 @@ void ApplyPatchesToFiles(const std::vector<Patch>& patches, PatchIndex index,
}
}
-static bool MemoryMatchesAt(u32 offset, const std::vector<u8>& value)
+static bool MemoryMatchesAt(const Core::CPUThreadGuard& guard, u32 offset,
+ const std::vector<u8>& value)
{
for (u32 i = 0; i < value.size(); ++i)
{
- auto result = PowerPC::HostTryReadU8(offset + i);
+ auto result = PowerPC::HostTryReadU8(guard, offset + i);
if (!result || result->value != value[i])
return false;
}
return true;
}
-static void ApplyMemoryPatch(u32 offset, const std::vector<u8>& value,
- const std::vector<u8>& original)
+static void ApplyMemoryPatch(const Core::CPUThreadGuard& guard, u32 offset,
+ const std::vector<u8>& value, const std::vector<u8>& original)
{
if (value.empty())
return;
- if (!original.empty() && !MemoryMatchesAt(offset, original))
+ if (!original.empty() && !MemoryMatchesAt(guard, offset, original))
return;
auto& system = Core::System::GetInstance();
const u32 size = static_cast<u32>(value.size());
for (u32 i = 0; i < size; ++i)
- PowerPC::HostTryWriteU8(value[i], offset + i);
+ PowerPC::HostTryWriteU8(guard, value[i], offset + i);
const u32 overlapping_hook_count = HLE::UnpatchRange(system, offset, offset + size);
if (overlapping_hook_count != 0)
{
@@ -516,17 +517,18 @@ static std::vector<u8> GetMemoryPatchValue(const Patch& patch, const Memory& mem
return memory_patch.m_value;
}
-static void ApplyMemoryPatch(const Patch& patch, const Memory& memory_patch)
+static void ApplyMemoryPatch(const Core::CPUThreadGuard& guard, const Patch& patch,
+ const Memory& memory_patch)
{
if (memory_patch.m_offset == 0)
return;
- ApplyMemoryPatch(memory_patch.m_offset | 0x80000000, GetMemoryPatchValue(patch, memory_patch),
- memory_patch.m_original);
+ ApplyMemoryPatch(guard, memory_patch.m_offset | 0x80000000,
+ GetMemoryPatchValue(patch, memory_patch), memory_patch.m_original);
}
-static void ApplySearchMemoryPatch(const Patch& patch, const Memory& memory_patch, u32 ram_start,
- u32 length)
+static void ApplySearchMemoryPatch(const Core::CPUThreadGuard& guard, const Patch& patch,
+ const Memory& memory_patch, u32 ram_start, u32 length)
{
if (memory_patch.m_original.empty() || memory_patch.m_align == 0)
return;
@@ -535,16 +537,16 @@ static void ApplySearchMemoryPatch(const Patch& patch, const Memory& memory_patc
for (u32 i = 0; i < length - (stride - 1); i += stride)
{
const u32 address = ram_start + i;
- if (MemoryMatchesAt(address, memory_patch.m_original))
+ if (MemoryMatchesAt(guard, address, memory_patch.m_original))
{
- ApplyMemoryPatch(address, GetMemoryPatchValue(patch, memory_patch), {});
+ ApplyMemoryPatch(guard, address, GetMemoryPatchValue(patch, memory_patch), {});
break;
}
}
}
-static void ApplyOcarinaMemoryPatch(const Patch& patch, const Memory& memory_patch, u32 ram_start,
- u32 length)
+static void ApplyOcarinaMemoryPatch(const Core::CPUThreadGuard& guard, const Patch& patch,
+ const Memory& memory_patch, u32 ram_start, u32 length)
{
if (memory_patch.m_offset == 0)
return;
@@ -557,19 +559,19 @@ static void ApplyOcarinaMemoryPatch(const Patch& patch, const Memory& memory_pat
{
// first find the pattern
const u32 address = ram_start + i;
- if (MemoryMatchesAt(address, value))
+ if (MemoryMatchesAt(guard, address, value))
{
for (; i < length; i += 4)
{
// from the pattern find the next blr instruction
const u32 blr_address = ram_start + i;
- auto blr = PowerPC::HostTryReadU32(blr_address);
+ auto blr = PowerPC::HostTryReadU32(guard, blr_address);
if (blr && blr->value == 0x4e800020)
{
// and replace it with a jump to the given offset
const u32 target = memory_patch.m_offset | 0x80000000;
const u32 jmp = ((target - blr_address) & 0x03fffffc) | 0x48000000;
- PowerPC::HostTryWriteU32(jmp, blr_address);
+ PowerPC::HostTryWriteU32(guard, jmp, blr_address);
const u32 overlapping_hook_count =
HLE::UnpatchRange(system, blr_address, blr_address + 4);
if (overlapping_hook_count != 0)
@@ -584,7 +586,7 @@ static void ApplyOcarinaMemoryPatch(const Patch& patch, const Memory& memory_pat
}
}
-void ApplyGeneralMemoryPatches(const std::vector<Patch>& patches)
+void ApplyGeneralMemoryPatches(const Core::CPUThreadGuard& guard, const std::vector<Patch>& patches)
{
auto& system = Core::System::GetInstance();
auto& system_memory = system.GetMemory();
@@ -597,14 +599,15 @@ void ApplyGeneralMemoryPatches(const std::vector<Patch>& patches)
continue;
if (memory.m_search)
- ApplySearchMemoryPatch(patch, memory, 0x80000000, system_memory.GetRamSize());
+ ApplySearchMemoryPatch(guard, patch, memory, 0x80000000, system_memory.GetRamSize());
else
- ApplyMemoryPatch(patch, memory);
+ ApplyMemoryPatch(guard, patch, memory);
}
}
}
-void ApplyApploaderMemoryPatches(const std::vector<Patch>& patches, u32 ram_address, u32 ram_length)
+void ApplyApploaderMemoryPatches(const Core::CPUThreadGuard& guard,
+ const std::vector<Patch>& patches, u32 ram_address, u32 ram_length)
{
for (const auto& patch : patches)
{
@@ -614,9 +617,9 @@ void ApplyApploaderMemoryPatches(const std::vector<Patch>& patches, u32 ram_addr
continue;
if (memory.m_ocarina)
- ApplyOcarinaMemoryPatch(patch, memory, ram_address, ram_length);
+ ApplyOcarinaMemoryPatch(guard, patch, memory, ram_address, ram_length);
else
- ApplySearchMemoryPatch(patch, memory, ram_address, ram_length);
+ ApplySearchMemoryPatch(guard, patch, memory, ram_address, ram_length);
}
}
}