Reorganize so that we're calling any memory protectives from the arena
This commit is contained in:
parent
4b53e9b52b
commit
e252c4a729
|
@ -113,12 +113,13 @@ public:
|
|||
void UnmapFromMemoryRegion(void* view, size_t size);
|
||||
|
||||
///
|
||||
/// Write protect a section from the memory region previously mapped by CreateView.
|
||||
/// Virtual protect a section from the memory region previously mapped by CreateView.
|
||||
///
|
||||
/// @param data Pointer to data to protect.
|
||||
/// @param size Size of the protection.
|
||||
/// @param flag What new permission to protect with.
|
||||
///
|
||||
bool WriteProtectMemoryRegion(u8* data, size_t size);
|
||||
bool VirtualProtectMemoryRegion(u8* data, size_t size, u64 flag);
|
||||
|
||||
private:
|
||||
#ifdef _WIN32
|
||||
|
|
|
@ -215,11 +215,11 @@ void MemArena::ReleaseMemoryRegion()
|
|||
}
|
||||
}
|
||||
|
||||
bool MemArena::WriteProtectMemoryRegion(u8* data, size_t size)
|
||||
bool MemArena::VirtualProtectMemoryRegion(u8* data, size_t size, u64 flag)
|
||||
{
|
||||
DWORD lpflOldProtect = 0;
|
||||
return static_cast<PVirtualProtect>(m_memory_functions.m_address_VirtualProtect)(
|
||||
data, size, PAGE_READONLY, &lpflOldProtect);
|
||||
data, size, flag, &lpflOldProtect);
|
||||
}
|
||||
|
||||
WindowsMemoryRegion* MemArena::EnsureSplitRegionForMapping(void* start_address, size_t size)
|
||||
|
|
|
@ -54,7 +54,12 @@ std::optional<size_t> MemoryManager::GetDirtyPageIndexFromAddress(u64 address)
|
|||
return (address & ~page_mask) >> 12;
|
||||
}
|
||||
|
||||
void MemoryManager::WriteProtectMemory()
|
||||
bool MemoryManager::VirtualProtectMemory(u8* data, size_t size, u64 flag)
|
||||
{
|
||||
return m_arena.VirtualProtectMemoryRegion(data, size, flag);
|
||||
}
|
||||
|
||||
void MemoryManager::WriteProtectPhysicalMemoryRegions()
|
||||
{
|
||||
for (const PhysicalMemoryRegion& region : m_physical_regions)
|
||||
{
|
||||
|
@ -63,12 +68,11 @@ void MemoryManager::WriteProtectMemory()
|
|||
size_t page_size = Common::PageSize();
|
||||
for (size_t i = 0; i < region.size; i += page_size)
|
||||
{
|
||||
bool change_protection =
|
||||
m_arena.WriteProtectMemoryRegion((*region.out_pointer) + i, page_size);
|
||||
bool change_protection = VirtualProtectMemory((*region.out_pointer) + i, page_size, PAGE_READONLY);
|
||||
if (!change_protection)
|
||||
{
|
||||
PanicAlertFmt(
|
||||
"Memory::Init(): Failed to write protect for this block of memory at 0x{:08X}.",
|
||||
"Memory::WriteProtectPhysicalMemoryRegions(): Failed to write protect for this block of memory at 0x{:08X}.",
|
||||
reinterpret_cast<u64>(*region.out_pointer));
|
||||
}
|
||||
std::optional<size_t> index =
|
||||
|
@ -105,7 +109,7 @@ void MemoryManager::InitMMIO(bool is_wii)
|
|||
|
||||
void MemoryManager::InitDirtyPages()
|
||||
{
|
||||
WriteProtectMemory();
|
||||
WriteProtectPhysicalMemoryRegions();
|
||||
}
|
||||
|
||||
void MemoryManager::Init()
|
||||
|
@ -675,7 +679,7 @@ void MemoryManager::SetPageDirtyBit(uintptr_t address, size_t size, bool dirty)
|
|||
|
||||
void MemoryManager::ResetDirtyPages()
|
||||
{
|
||||
WriteProtectMemory();
|
||||
WriteProtectPhysicalMemoryRegions();
|
||||
}
|
||||
|
||||
} // namespace Memory
|
||||
|
|
|
@ -135,6 +135,7 @@ public:
|
|||
bool IsPageDirty(uintptr_t address);
|
||||
void SetPageDirtyBit(uintptr_t address, size_t size, bool dirty);
|
||||
void ResetDirtyPages();
|
||||
bool VirtualProtectMemory(u8* data, size_t size, u64 flag);
|
||||
|
||||
std::map<u64, u8>& GetDirtyPages() { return m_dirty_pages; }
|
||||
|
||||
|
@ -265,7 +266,8 @@ private:
|
|||
std::map<u64, u8> m_dirty_pages;
|
||||
|
||||
std::optional<size_t> GetDirtyPageIndexFromAddress(u64 address);
|
||||
void WriteProtectMemory();
|
||||
void WriteProtectPhysicalMemoryRegions();
|
||||
|
||||
void InitMMIO(bool is_wii);
|
||||
};
|
||||
} // namespace Memory
|
||||
|
|
|
@ -62,21 +62,21 @@ static LONG NTAPI Handler(PEXCEPTION_POINTERS pPtrs)
|
|||
// virtual address of the inaccessible data
|
||||
uintptr_t fault_address = (uintptr_t)pPtrs->ExceptionRecord->ExceptionInformation[1];
|
||||
SContext* ctx = pPtrs->ContextRecord;
|
||||
if (Core::System::GetInstance().GetJitInterface().HandleFault(fault_address, ctx))
|
||||
Core::System& system = Core::System::GetInstance();
|
||||
Memory::MemoryManager& memory = system.GetMemory();
|
||||
if (system.GetJitInterface().HandleFault(fault_address, ctx))
|
||||
{
|
||||
return EXCEPTION_CONTINUE_EXECUTION;
|
||||
}
|
||||
else if (!Core::System::GetInstance().GetMemory().IsPageDirty(fault_address))
|
||||
else if (!memory.IsPageDirty(fault_address))
|
||||
{
|
||||
Core::System::GetInstance().GetMemory().SetPageDirtyBit(fault_address, 1, true);
|
||||
memory.SetPageDirtyBit(fault_address, 1, true);
|
||||
|
||||
size_t page_size = Common::PageSize();
|
||||
size_t page_mask = page_size - 1;
|
||||
u64 page_index = fault_address & page_mask;
|
||||
DWORD lpflOldProtect = 0;
|
||||
bool change_protection =
|
||||
VirtualProtect(reinterpret_cast<u8*>(fault_address), page_size - page_index,
|
||||
PAGE_READWRITE, &lpflOldProtect);
|
||||
bool change_protection = memory.VirtualProtectMemory(reinterpret_cast<u8*>(fault_address),
|
||||
page_size - page_index, PAGE_READWRITE);
|
||||
if (!change_protection)
|
||||
{
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
|
|
Loading…
Reference in New Issue