From 3ce18fd96002e7c4a2bc36d1cda78e29a6279a67 Mon Sep 17 00:00:00 2001 From: Eladash Date: Sun, 11 Aug 2019 21:04:17 +0300 Subject: [PATCH] Implement vm::page_executable (#6330) Fixes segfaults when attenpting to set segfaults on non-executable memory. --- rpcs3/Emu/Cell/PPUModule.cpp | 6 ------ rpcs3/Emu/Cell/PPUThread.cpp | 1 + rpcs3/Emu/Cell/lv2/sys_overlay.cpp | 5 ----- rpcs3/Emu/Memory/vm.cpp | 18 +++++++++++++----- rpcs3/rpcs3qt/breakpoint_list.cpp | 2 +- 5 files changed, 15 insertions(+), 17 deletions(-) diff --git a/rpcs3/Emu/Cell/PPUModule.cpp b/rpcs3/Emu/Cell/PPUModule.cpp index 9cb3714e9f..e709c7f25f 100644 --- a/rpcs3/Emu/Cell/PPUModule.cpp +++ b/rpcs3/Emu/Cell/PPUModule.cpp @@ -1035,12 +1035,6 @@ void ppu_unload_prx(const lv2_prx& prx) for (auto& seg : prx.segs) { - if (seg.flags & 1) - { - // Segment was considered executable thus needing to free exec data - utils::memory_decommit(vm::g_exec_addr + size_t{seg.addr} * 2, size_t{seg.size} * 2); - } - vm::dealloc(seg.addr, vm::main); } } diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index 0b9bab3bd8..57c705df9f 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -271,6 +271,7 @@ extern void ppu_register_range(u32 addr, u32 size) // Register executable range at utils::memory_commit(&ppu_ref(addr), size * 2, utils::protection::rw); + vm::page_protect(addr, align(size, 0x10000), 0, vm::page_executable); const u32 fallback = ::narrow(g_cfg.core.ppu_decoder == ppu_decoder_type::llvm ? reinterpret_cast(ppu_recompiler_fallback) : reinterpret_cast(ppu_fallback)); diff --git a/rpcs3/Emu/Cell/lv2/sys_overlay.cpp b/rpcs3/Emu/Cell/lv2/sys_overlay.cpp index e79a15269f..d63b5aa1d4 100644 --- a/rpcs3/Emu/Cell/lv2/sys_overlay.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_overlay.cpp @@ -101,11 +101,6 @@ error_code sys_overlay_unload_module(u32 ovlmid) for (auto& seg : _main->segs) { - if (seg.flags & 1) - { - utils::memory_decommit(vm::g_exec_addr + size_t{seg.addr} * 2, size_t{seg.size} * 2); - } - vm::dealloc(seg.addr); } diff --git a/rpcs3/Emu/Memory/vm.cpp b/rpcs3/Emu/Memory/vm.cpp index bc0b871d8b..e8cdbcb0dd 100644 --- a/rpcs3/Emu/Memory/vm.cpp +++ b/rpcs3/Emu/Memory/vm.cpp @@ -371,6 +371,7 @@ namespace vm if (flags & page_executable) { + // TODO utils::memory_commit(g_exec_addr + addr * 2, size * 2); } @@ -424,10 +425,12 @@ namespace vm if (i < end) { - g_pages[i].flags |= flags_set; - g_pages[i].flags &= ~flags_clear; + new_val = g_pages[i].flags; + new_val |= flags_set; + new_val &= ~flags_clear; - new_val = g_pages[i].flags & (page_readable | page_writable); + g_pages[i].flags.release(new_val); + new_val &= (page_readable | page_writable); } if (new_val != start_value) @@ -464,9 +467,14 @@ namespace vm break; } - if (g_pages[i].flags & page_executable) + if (size == 0) { - is_exec = true; + is_exec = !!(g_pages[i].flags & page_executable); + } + else + { + // Must be consistent + verify(HERE), is_exec == !!(g_pages[i].flags & page_executable); } size += 4096; diff --git a/rpcs3/rpcs3qt/breakpoint_list.cpp b/rpcs3/rpcs3qt/breakpoint_list.cpp index e9388aef82..89fdb01d02 100644 --- a/rpcs3/rpcs3qt/breakpoint_list.cpp +++ b/rpcs3/rpcs3qt/breakpoint_list.cpp @@ -91,7 +91,7 @@ void breakpoint_list::HandleBreakpointRequest(u32 loc) { const auto cpu = this->cpu.lock(); - if (cpu->id_type() == 1 && vm::check_addr(loc)) + if (cpu->id_type() == 1 && vm::check_addr(loc, 1, vm::page_allocated | vm::page_executable)) { AddBreakpoint(loc); }