diff options
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/arm/arm_interface.cpp | 8 | ||||
| -rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic_32.cpp | 21 | ||||
| -rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic_64.cpp | 21 |
3 files changed, 44 insertions, 6 deletions
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() { | |||
| 145 | // Notify the debugger and go to sleep if a breakpoint was hit, | 145 | // Notify the debugger and go to sleep if a breakpoint was hit, |
| 146 | // or if the thread is unable to continue for any reason. | 146 | // or if the thread is unable to continue for any reason. |
| 147 | if (Has(hr, breakpoint) || Has(hr, no_execute)) { | 147 | if (Has(hr, breakpoint) || Has(hr, no_execute)) { |
| 148 | RewindBreakpointInstruction(); | 148 | if (!Has(hr, no_execute)) { |
| 149 | RewindBreakpointInstruction(); | ||
| 150 | } | ||
| 149 | if (system.DebuggerEnabled()) { | 151 | if (system.DebuggerEnabled()) { |
| 150 | system.GetDebugger().NotifyThreadStopped(current_thread); | 152 | system.GetDebugger().NotifyThreadStopped(current_thread); |
| 153 | } else { | ||
| 154 | LogBacktrace(); | ||
| 151 | } | 155 | } |
| 152 | current_thread->RequestSuspend(Kernel::SuspendType::Debug); | 156 | current_thread->RequestSuspend(SuspendType::Debug); |
| 153 | break; | 157 | break; |
| 154 | } | 158 | } |
| 155 | 159 | ||
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 { | |||
| 29 | public: | 29 | public: |
| 30 | explicit DynarmicCallbacks32(ARM_Dynarmic_32& parent_) | 30 | explicit DynarmicCallbacks32(ARM_Dynarmic_32& parent_) |
| 31 | : parent{parent_}, | 31 | : parent{parent_}, |
| 32 | memory(parent.system.Memory()), debugger_enabled{parent.system.DebuggerEnabled()} {} | 32 | memory(parent.system.Memory()), debugger_enabled{parent.system.DebuggerEnabled()}, |
| 33 | check_memory_access{debugger_enabled || | ||
| 34 | !Settings::values.cpuopt_ignore_memory_aborts.GetValue()} {} | ||
| 33 | 35 | ||
| 34 | u8 MemoryRead8(u32 vaddr) override { | 36 | u8 MemoryRead8(u32 vaddr) override { |
| 35 | CheckMemoryAccess(vaddr, 1, Kernel::DebugWatchpointType::Read); | 37 | CheckMemoryAccess(vaddr, 1, Kernel::DebugWatchpointType::Read); |
| @@ -154,6 +156,17 @@ public: | |||
| 154 | } | 156 | } |
| 155 | 157 | ||
| 156 | bool CheckMemoryAccess(VAddr addr, u64 size, Kernel::DebugWatchpointType type) { | 158 | bool CheckMemoryAccess(VAddr addr, u64 size, Kernel::DebugWatchpointType type) { |
| 159 | if (!check_memory_access) { | ||
| 160 | return true; | ||
| 161 | } | ||
| 162 | |||
| 163 | if (!memory.IsValidVirtualAddressRange(addr, size)) { | ||
| 164 | LOG_CRITICAL(Core_ARM, "Stopping execution due to unmapped memory access at {:#x}", | ||
| 165 | addr); | ||
| 166 | parent.jit.load()->HaltExecution(ARM_Interface::no_execute); | ||
| 167 | return false; | ||
| 168 | } | ||
| 169 | |||
| 157 | if (!debugger_enabled) { | 170 | if (!debugger_enabled) { |
| 158 | return true; | 171 | return true; |
| 159 | } | 172 | } |
| @@ -181,7 +194,8 @@ public: | |||
| 181 | ARM_Dynarmic_32& parent; | 194 | ARM_Dynarmic_32& parent; |
| 182 | Core::Memory::Memory& memory; | 195 | Core::Memory::Memory& memory; |
| 183 | std::size_t num_interpreted_instructions{}; | 196 | std::size_t num_interpreted_instructions{}; |
| 184 | bool debugger_enabled{}; | 197 | const bool debugger_enabled{}; |
| 198 | const bool check_memory_access{}; | ||
| 185 | static constexpr u64 minimum_run_cycles = 10000U; | 199 | static constexpr u64 minimum_run_cycles = 10000U; |
| 186 | }; | 200 | }; |
| 187 | 201 | ||
| @@ -264,6 +278,9 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable* | |||
| 264 | if (!Settings::values.cpuopt_recompile_exclusives) { | 278 | if (!Settings::values.cpuopt_recompile_exclusives) { |
| 265 | config.recompile_on_exclusive_fastmem_failure = false; | 279 | config.recompile_on_exclusive_fastmem_failure = false; |
| 266 | } | 280 | } |
| 281 | if (!Settings::values.cpuopt_ignore_memory_aborts) { | ||
| 282 | config.check_halt_on_memory_access = true; | ||
| 283 | } | ||
| 267 | } else { | 284 | } else { |
| 268 | // Unsafe optimizations | 285 | // Unsafe optimizations |
| 269 | if (Settings::values.cpu_accuracy.GetValue() == Settings::CPUAccuracy::Unsafe) { | 286 | 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 { | |||
| 29 | public: | 29 | public: |
| 30 | explicit DynarmicCallbacks64(ARM_Dynarmic_64& parent_) | 30 | explicit DynarmicCallbacks64(ARM_Dynarmic_64& parent_) |
| 31 | : parent{parent_}, | 31 | : parent{parent_}, |
| 32 | memory(parent.system.Memory()), debugger_enabled{parent.system.DebuggerEnabled()} {} | 32 | memory(parent.system.Memory()), debugger_enabled{parent.system.DebuggerEnabled()}, |
| 33 | check_memory_access{debugger_enabled || | ||
| 34 | !Settings::values.cpuopt_ignore_memory_aborts.GetValue()} {} | ||
| 33 | 35 | ||
| 34 | u8 MemoryRead8(u64 vaddr) override { | 36 | u8 MemoryRead8(u64 vaddr) override { |
| 35 | CheckMemoryAccess(vaddr, 1, Kernel::DebugWatchpointType::Read); | 37 | CheckMemoryAccess(vaddr, 1, Kernel::DebugWatchpointType::Read); |
| @@ -198,6 +200,17 @@ public: | |||
| 198 | } | 200 | } |
| 199 | 201 | ||
| 200 | bool CheckMemoryAccess(VAddr addr, u64 size, Kernel::DebugWatchpointType type) { | 202 | bool CheckMemoryAccess(VAddr addr, u64 size, Kernel::DebugWatchpointType type) { |
| 203 | if (!check_memory_access) { | ||
| 204 | return true; | ||
| 205 | } | ||
| 206 | |||
| 207 | if (!memory.IsValidVirtualAddressRange(addr, size)) { | ||
| 208 | LOG_CRITICAL(Core_ARM, "Stopping execution due to unmapped memory access at {:#x}", | ||
| 209 | addr); | ||
| 210 | parent.jit.load()->HaltExecution(ARM_Interface::no_execute); | ||
| 211 | return false; | ||
| 212 | } | ||
| 213 | |||
| 201 | if (!debugger_enabled) { | 214 | if (!debugger_enabled) { |
| 202 | return true; | 215 | return true; |
| 203 | } | 216 | } |
| @@ -226,7 +239,8 @@ public: | |||
| 226 | Core::Memory::Memory& memory; | 239 | Core::Memory::Memory& memory; |
| 227 | u64 tpidrro_el0 = 0; | 240 | u64 tpidrro_el0 = 0; |
| 228 | u64 tpidr_el0 = 0; | 241 | u64 tpidr_el0 = 0; |
| 229 | bool debugger_enabled{}; | 242 | const bool debugger_enabled{}; |
| 243 | const bool check_memory_access{}; | ||
| 230 | static constexpr u64 minimum_run_cycles = 10000U; | 244 | static constexpr u64 minimum_run_cycles = 10000U; |
| 231 | }; | 245 | }; |
| 232 | 246 | ||
| @@ -323,6 +337,9 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable* | |||
| 323 | if (!Settings::values.cpuopt_recompile_exclusives) { | 337 | if (!Settings::values.cpuopt_recompile_exclusives) { |
| 324 | config.recompile_on_exclusive_fastmem_failure = false; | 338 | config.recompile_on_exclusive_fastmem_failure = false; |
| 325 | } | 339 | } |
| 340 | if (!Settings::values.cpuopt_ignore_memory_aborts) { | ||
| 341 | config.check_halt_on_memory_access = true; | ||
| 342 | } | ||
| 326 | } else { | 343 | } else { |
| 327 | // Unsafe optimizations | 344 | // Unsafe optimizations |
| 328 | if (Settings::values.cpu_accuracy.GetValue() == Settings::CPUAccuracy::Unsafe) { | 345 | if (Settings::values.cpu_accuracy.GetValue() == Settings::CPUAccuracy::Unsafe) { |