mirror of
				https://git.suyu.dev/suyu/suyu
				synced 2025-11-04 00:49:02 -06:00 
			
		
		
		
	core: add option to break on unmapped access
This commit is contained in:
		@@ -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;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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<Dynarmic::A32::Jit> 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) {
 | 
			
		||||
 
 | 
			
		||||
@@ -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<Dynarmic::A64::Jit> 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) {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user