From 6072b22a0b9a1d84c389e8231fe4b6a97e60d55f Mon Sep 17 00:00:00 2001 From: Liam Date: Thu, 1 Dec 2022 22:48:43 -0500 Subject: core: add option to break on unmapped access --- src/core/arm/arm_interface.cpp | 8 ++++++-- src/core/arm/dynarmic/arm_dynarmic_32.cpp | 21 +++++++++++++++++++-- src/core/arm/dynarmic/arm_dynarmic_64.cpp | 21 +++++++++++++++++++-- 3 files changed, 44 insertions(+), 6 deletions(-) (limited to 'src/core') diff --git a/src/core/arm/arm_interface.cpp b/src/core/arm/arm_interface.cpp index 29ba562dc..2df7b0ee8 100644 --- a/src/core/arm/arm_interface.cpp +++ b/src/core/arm/arm_interface.cpp @@ -145,11 +145,15 @@ void ARM_Interface::Run() { // Notify the debugger and go to sleep if a breakpoint was hit, // or if the thread is unable to continue for any reason. if (Has(hr, breakpoint) || Has(hr, no_execute)) { - RewindBreakpointInstruction(); + if (!Has(hr, no_execute)) { + RewindBreakpointInstruction(); + } if (system.DebuggerEnabled()) { system.GetDebugger().NotifyThreadStopped(current_thread); + } else { + LogBacktrace(); } - current_thread->RequestSuspend(Kernel::SuspendType::Debug); + current_thread->RequestSuspend(SuspendType::Debug); break; } diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp index 227e06ea1..947747d36 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp @@ -29,7 +29,9 @@ class DynarmicCallbacks32 : public Dynarmic::A32::UserCallbacks { public: explicit DynarmicCallbacks32(ARM_Dynarmic_32& parent_) : parent{parent_}, - memory(parent.system.Memory()), debugger_enabled{parent.system.DebuggerEnabled()} {} + memory(parent.system.Memory()), debugger_enabled{parent.system.DebuggerEnabled()}, + check_memory_access{debugger_enabled || + !Settings::values.cpuopt_ignore_memory_aborts.GetValue()} {} u8 MemoryRead8(u32 vaddr) override { CheckMemoryAccess(vaddr, 1, Kernel::DebugWatchpointType::Read); @@ -154,6 +156,17 @@ public: } bool CheckMemoryAccess(VAddr addr, u64 size, Kernel::DebugWatchpointType type) { + if (!check_memory_access) { + return true; + } + + if (!memory.IsValidVirtualAddressRange(addr, size)) { + LOG_CRITICAL(Core_ARM, "Stopping execution due to unmapped memory access at {:#x}", + addr); + parent.jit.load()->HaltExecution(ARM_Interface::no_execute); + return false; + } + if (!debugger_enabled) { return true; } @@ -181,7 +194,8 @@ public: ARM_Dynarmic_32& parent; Core::Memory::Memory& memory; std::size_t num_interpreted_instructions{}; - bool debugger_enabled{}; + const bool debugger_enabled{}; + const bool check_memory_access{}; static constexpr u64 minimum_run_cycles = 10000U; }; @@ -264,6 +278,9 @@ std::shared_ptr ARM_Dynarmic_32::MakeJit(Common::PageTable* if (!Settings::values.cpuopt_recompile_exclusives) { config.recompile_on_exclusive_fastmem_failure = false; } + if (!Settings::values.cpuopt_ignore_memory_aborts) { + config.check_halt_on_memory_access = true; + } } else { // Unsafe optimizations if (Settings::values.cpu_accuracy.GetValue() == Settings::CPUAccuracy::Unsafe) { diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp index cb53d64ba..3df943df7 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp @@ -29,7 +29,9 @@ class DynarmicCallbacks64 : public Dynarmic::A64::UserCallbacks { public: explicit DynarmicCallbacks64(ARM_Dynarmic_64& parent_) : parent{parent_}, - memory(parent.system.Memory()), debugger_enabled{parent.system.DebuggerEnabled()} {} + memory(parent.system.Memory()), debugger_enabled{parent.system.DebuggerEnabled()}, + check_memory_access{debugger_enabled || + !Settings::values.cpuopt_ignore_memory_aborts.GetValue()} {} u8 MemoryRead8(u64 vaddr) override { CheckMemoryAccess(vaddr, 1, Kernel::DebugWatchpointType::Read); @@ -198,6 +200,17 @@ public: } bool CheckMemoryAccess(VAddr addr, u64 size, Kernel::DebugWatchpointType type) { + if (!check_memory_access) { + return true; + } + + if (!memory.IsValidVirtualAddressRange(addr, size)) { + LOG_CRITICAL(Core_ARM, "Stopping execution due to unmapped memory access at {:#x}", + addr); + parent.jit.load()->HaltExecution(ARM_Interface::no_execute); + return false; + } + if (!debugger_enabled) { return true; } @@ -226,7 +239,8 @@ public: Core::Memory::Memory& memory; u64 tpidrro_el0 = 0; u64 tpidr_el0 = 0; - bool debugger_enabled{}; + const bool debugger_enabled{}; + const bool check_memory_access{}; static constexpr u64 minimum_run_cycles = 10000U; }; @@ -323,6 +337,9 @@ std::shared_ptr ARM_Dynarmic_64::MakeJit(Common::PageTable* if (!Settings::values.cpuopt_recompile_exclusives) { config.recompile_on_exclusive_fastmem_failure = false; } + if (!Settings::values.cpuopt_ignore_memory_aborts) { + config.check_halt_on_memory_access = true; + } } else { // Unsafe optimizations if (Settings::values.cpu_accuracy.GetValue() == Settings::CPUAccuracy::Unsafe) { -- cgit v1.2.3