diff options
| author | 2022-05-31 14:37:37 -0400 | |
|---|---|---|
| committer | 2022-06-01 02:15:15 -0400 | |
| commit | 989d4a7a41f449af0ea09e34bee331a3a3ac8170 (patch) | |
| tree | df24bd9d7e6942b939e3ea42d08c0d65006e539f /src/core/arm/dynarmic | |
| parent | core/debugger: Implement new GDB stub debugger (diff) | |
| download | yuzu-989d4a7a41f449af0ea09e34bee331a3a3ac8170.tar.gz yuzu-989d4a7a41f449af0ea09e34bee331a3a3ac8170.tar.xz yuzu-989d4a7a41f449af0ea09e34bee331a3a3ac8170.zip | |
core/debugger: Improved stepping mechanism and misc fixes
Diffstat (limited to 'src/core/arm/dynarmic')
| -rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic_32.cpp | 45 | ||||
| -rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic_32.h | 9 | ||||
| -rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic_64.cpp | 45 | ||||
| -rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic_64.h | 9 |
4 files changed, 32 insertions, 76 deletions
diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp index 894c1c527..7c82d0b96 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp | |||
| @@ -26,10 +26,6 @@ namespace Core { | |||
| 26 | 26 | ||
| 27 | using namespace Common::Literals; | 27 | using namespace Common::Literals; |
| 28 | 28 | ||
| 29 | constexpr Dynarmic::HaltReason break_loop = Dynarmic::HaltReason::UserDefined2; | ||
| 30 | constexpr Dynarmic::HaltReason svc_call = Dynarmic::HaltReason::UserDefined3; | ||
| 31 | constexpr Dynarmic::HaltReason breakpoint = Dynarmic::HaltReason::UserDefined4; | ||
| 32 | |||
| 33 | class DynarmicCallbacks32 : public Dynarmic::A32::UserCallbacks { | 29 | class DynarmicCallbacks32 : public Dynarmic::A32::UserCallbacks { |
| 34 | public: | 30 | public: |
| 35 | explicit DynarmicCallbacks32(ARM_Dynarmic_32& parent_) | 31 | explicit DynarmicCallbacks32(ARM_Dynarmic_32& parent_) |
| @@ -82,8 +78,8 @@ public: | |||
| 82 | 78 | ||
| 83 | void ExceptionRaised(u32 pc, Dynarmic::A32::Exception exception) override { | 79 | void ExceptionRaised(u32 pc, Dynarmic::A32::Exception exception) override { |
| 84 | if (parent.system.DebuggerEnabled()) { | 80 | if (parent.system.DebuggerEnabled()) { |
| 85 | parent.breakpoint_pc = pc; | 81 | parent.jit.load()->Regs()[15] = pc; |
| 86 | parent.jit.load()->HaltExecution(breakpoint); | 82 | parent.jit.load()->HaltExecution(ARM_Interface::breakpoint); |
| 87 | return; | 83 | return; |
| 88 | } | 84 | } |
| 89 | 85 | ||
| @@ -95,7 +91,7 @@ public: | |||
| 95 | 91 | ||
| 96 | void CallSVC(u32 swi) override { | 92 | void CallSVC(u32 swi) override { |
| 97 | parent.svc_swi = swi; | 93 | parent.svc_swi = swi; |
| 98 | parent.jit.load()->HaltExecution(svc_call); | 94 | parent.jit.load()->HaltExecution(ARM_Interface::svc_call); |
| 99 | } | 95 | } |
| 100 | 96 | ||
| 101 | void AddTicks(u64 ticks) override { | 97 | void AddTicks(u64 ticks) override { |
| @@ -240,35 +236,16 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable* | |||
| 240 | return std::make_unique<Dynarmic::A32::Jit>(config); | 236 | return std::make_unique<Dynarmic::A32::Jit>(config); |
| 241 | } | 237 | } |
| 242 | 238 | ||
| 243 | void ARM_Dynarmic_32::Run() { | 239 | Dynarmic::HaltReason ARM_Dynarmic_32::RunJit() { |
| 244 | while (true) { | 240 | return jit.load()->Run(); |
| 245 | const auto hr = ShouldStep() ? jit.load()->Step() : jit.load()->Run(); | 241 | } |
| 246 | if (Has(hr, svc_call)) { | ||
| 247 | Kernel::Svc::Call(system, svc_swi); | ||
| 248 | } | ||
| 249 | |||
| 250 | // Check to see if breakpoint is triggered. | ||
| 251 | // Recheck step condition in case stop is no longer desired. | ||
| 252 | Kernel::KThread* current_thread = system.Kernel().GetCurrentEmuThread(); | ||
| 253 | if (Has(hr, breakpoint)) { | ||
| 254 | jit.load()->Regs()[15] = breakpoint_pc; | ||
| 255 | 242 | ||
| 256 | if (system.GetDebugger().NotifyThreadStopped(current_thread)) { | 243 | Dynarmic::HaltReason ARM_Dynarmic_32::StepJit() { |
| 257 | current_thread->RequestSuspend(Kernel::SuspendType::Debug); | 244 | return jit.load()->Step(); |
| 258 | } | 245 | } |
| 259 | break; | ||
| 260 | } | ||
| 261 | if (ShouldStep()) { | ||
| 262 | // When stepping, this should be the only thread running. | ||
| 263 | ASSERT(system.GetDebugger().NotifyThreadStopped(current_thread)); | ||
| 264 | current_thread->RequestSuspend(Kernel::SuspendType::Debug); | ||
| 265 | break; | ||
| 266 | } | ||
| 267 | 246 | ||
| 268 | if (Has(hr, break_loop) || !uses_wall_clock) { | 247 | u32 ARM_Dynarmic_32::GetSvcNumber() const { |
| 269 | break; | 248 | return svc_swi; |
| 270 | } | ||
| 271 | } | ||
| 272 | } | 249 | } |
| 273 | 250 | ||
| 274 | ARM_Dynarmic_32::ARM_Dynarmic_32(System& system_, CPUInterrupts& interrupt_handlers_, | 251 | ARM_Dynarmic_32::ARM_Dynarmic_32(System& system_, CPUInterrupts& interrupt_handlers_, |
diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.h b/src/core/arm/dynarmic/arm_dynarmic_32.h index 0557d5940..5b1d60005 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.h +++ b/src/core/arm/dynarmic/arm_dynarmic_32.h | |||
| @@ -41,7 +41,6 @@ public: | |||
| 41 | void SetVectorReg(int index, u128 value) override; | 41 | void SetVectorReg(int index, u128 value) override; |
| 42 | u32 GetPSTATE() const override; | 42 | u32 GetPSTATE() const override; |
| 43 | void SetPSTATE(u32 pstate) override; | 43 | void SetPSTATE(u32 pstate) override; |
| 44 | void Run() override; | ||
| 45 | VAddr GetTlsAddress() const override; | 44 | VAddr GetTlsAddress() const override; |
| 46 | void SetTlsAddress(VAddr address) override; | 45 | void SetTlsAddress(VAddr address) override; |
| 47 | void SetTPIDR_EL0(u64 value) override; | 46 | void SetTPIDR_EL0(u64 value) override; |
| @@ -69,6 +68,11 @@ public: | |||
| 69 | 68 | ||
| 70 | std::vector<BacktraceEntry> GetBacktrace() const override; | 69 | std::vector<BacktraceEntry> GetBacktrace() const override; |
| 71 | 70 | ||
| 71 | protected: | ||
| 72 | Dynarmic::HaltReason RunJit() override; | ||
| 73 | Dynarmic::HaltReason StepJit() override; | ||
| 74 | u32 GetSvcNumber() const override; | ||
| 75 | |||
| 72 | private: | 76 | private: |
| 73 | std::shared_ptr<Dynarmic::A32::Jit> MakeJit(Common::PageTable* page_table) const; | 77 | std::shared_ptr<Dynarmic::A32::Jit> MakeJit(Common::PageTable* page_table) const; |
| 74 | 78 | ||
| @@ -94,9 +98,6 @@ private: | |||
| 94 | 98 | ||
| 95 | // SVC callback | 99 | // SVC callback |
| 96 | u32 svc_swi{}; | 100 | u32 svc_swi{}; |
| 97 | |||
| 98 | // Debug restart address | ||
| 99 | u32 breakpoint_pc{}; | ||
| 100 | }; | 101 | }; |
| 101 | 102 | ||
| 102 | } // namespace Core | 103 | } // namespace Core |
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp index 1f596cfef..d4c67eafd 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp | |||
| @@ -26,10 +26,6 @@ namespace Core { | |||
| 26 | using Vector = Dynarmic::A64::Vector; | 26 | using Vector = Dynarmic::A64::Vector; |
| 27 | using namespace Common::Literals; | 27 | using namespace Common::Literals; |
| 28 | 28 | ||
| 29 | constexpr Dynarmic::HaltReason break_loop = Dynarmic::HaltReason::UserDefined2; | ||
| 30 | constexpr Dynarmic::HaltReason svc_call = Dynarmic::HaltReason::UserDefined3; | ||
| 31 | constexpr Dynarmic::HaltReason breakpoint = Dynarmic::HaltReason::UserDefined4; | ||
| 32 | |||
| 33 | class DynarmicCallbacks64 : public Dynarmic::A64::UserCallbacks { | 29 | class DynarmicCallbacks64 : public Dynarmic::A64::UserCallbacks { |
| 34 | public: | 30 | public: |
| 35 | explicit DynarmicCallbacks64(ARM_Dynarmic_64& parent_) | 31 | explicit DynarmicCallbacks64(ARM_Dynarmic_64& parent_) |
| @@ -123,8 +119,8 @@ public: | |||
| 123 | return; | 119 | return; |
| 124 | default: | 120 | default: |
| 125 | if (parent.system.DebuggerEnabled()) { | 121 | if (parent.system.DebuggerEnabled()) { |
| 126 | parent.breakpoint_pc = pc; | 122 | parent.jit.load()->SetPC(pc); |
| 127 | parent.jit.load()->HaltExecution(breakpoint); | 123 | parent.jit.load()->HaltExecution(ARM_Interface::breakpoint); |
| 128 | return; | 124 | return; |
| 129 | } | 125 | } |
| 130 | 126 | ||
| @@ -136,7 +132,7 @@ public: | |||
| 136 | 132 | ||
| 137 | void CallSVC(u32 swi) override { | 133 | void CallSVC(u32 swi) override { |
| 138 | parent.svc_swi = swi; | 134 | parent.svc_swi = swi; |
| 139 | parent.jit.load()->HaltExecution(svc_call); | 135 | parent.jit.load()->HaltExecution(ARM_Interface::svc_call); |
| 140 | } | 136 | } |
| 141 | 137 | ||
| 142 | void AddTicks(u64 ticks) override { | 138 | void AddTicks(u64 ticks) override { |
| @@ -300,35 +296,16 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable* | |||
| 300 | return std::make_shared<Dynarmic::A64::Jit>(config); | 296 | return std::make_shared<Dynarmic::A64::Jit>(config); |
| 301 | } | 297 | } |
| 302 | 298 | ||
| 303 | void ARM_Dynarmic_64::Run() { | 299 | Dynarmic::HaltReason ARM_Dynarmic_64::RunJit() { |
| 304 | while (true) { | 300 | return jit.load()->Run(); |
| 305 | const auto hr = jit.load()->Run(); | 301 | } |
| 306 | if (Has(hr, svc_call)) { | ||
| 307 | Kernel::Svc::Call(system, svc_swi); | ||
| 308 | } | ||
| 309 | |||
| 310 | // Check to see if breakpoint is triggered. | ||
| 311 | // Recheck step condition in case stop is no longer desired. | ||
| 312 | Kernel::KThread* current_thread = system.Kernel().GetCurrentEmuThread(); | ||
| 313 | if (Has(hr, breakpoint)) { | ||
| 314 | jit.load()->SetPC(breakpoint_pc); | ||
| 315 | 302 | ||
| 316 | if (system.GetDebugger().NotifyThreadStopped(current_thread)) { | 303 | Dynarmic::HaltReason ARM_Dynarmic_64::StepJit() { |
| 317 | current_thread->RequestSuspend(Kernel::SuspendType::Debug); | 304 | return jit.load()->Step(); |
| 318 | } | 305 | } |
| 319 | break; | ||
| 320 | } | ||
| 321 | if (ShouldStep()) { | ||
| 322 | // When stepping, this should be the only thread running. | ||
| 323 | ASSERT(system.GetDebugger().NotifyThreadStopped(current_thread)); | ||
| 324 | current_thread->RequestSuspend(Kernel::SuspendType::Debug); | ||
| 325 | break; | ||
| 326 | } | ||
| 327 | 306 | ||
| 328 | if (Has(hr, break_loop) || !uses_wall_clock) { | 307 | u32 ARM_Dynarmic_64::GetSvcNumber() const { |
| 329 | break; | 308 | return svc_swi; |
| 330 | } | ||
| 331 | } | ||
| 332 | } | 309 | } |
| 333 | 310 | ||
| 334 | ARM_Dynarmic_64::ARM_Dynarmic_64(System& system_, CPUInterrupts& interrupt_handlers_, | 311 | ARM_Dynarmic_64::ARM_Dynarmic_64(System& system_, CPUInterrupts& interrupt_handlers_, |
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.h b/src/core/arm/dynarmic/arm_dynarmic_64.h index aa7054e0c..abfbc3c3f 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.h +++ b/src/core/arm/dynarmic/arm_dynarmic_64.h | |||
| @@ -39,7 +39,6 @@ public: | |||
| 39 | void SetVectorReg(int index, u128 value) override; | 39 | void SetVectorReg(int index, u128 value) override; |
| 40 | u32 GetPSTATE() const override; | 40 | u32 GetPSTATE() const override; |
| 41 | void SetPSTATE(u32 pstate) override; | 41 | void SetPSTATE(u32 pstate) override; |
| 42 | void Run() override; | ||
| 43 | VAddr GetTlsAddress() const override; | 42 | VAddr GetTlsAddress() const override; |
| 44 | void SetTlsAddress(VAddr address) override; | 43 | void SetTlsAddress(VAddr address) override; |
| 45 | void SetTPIDR_EL0(u64 value) override; | 44 | void SetTPIDR_EL0(u64 value) override; |
| @@ -63,6 +62,11 @@ public: | |||
| 63 | 62 | ||
| 64 | std::vector<BacktraceEntry> GetBacktrace() const override; | 63 | std::vector<BacktraceEntry> GetBacktrace() const override; |
| 65 | 64 | ||
| 65 | protected: | ||
| 66 | Dynarmic::HaltReason RunJit() override; | ||
| 67 | Dynarmic::HaltReason StepJit() override; | ||
| 68 | u32 GetSvcNumber() const override; | ||
| 69 | |||
| 66 | private: | 70 | private: |
| 67 | std::shared_ptr<Dynarmic::A64::Jit> MakeJit(Common::PageTable* page_table, | 71 | std::shared_ptr<Dynarmic::A64::Jit> MakeJit(Common::PageTable* page_table, |
| 68 | std::size_t address_space_bits) const; | 72 | std::size_t address_space_bits) const; |
| @@ -87,9 +91,6 @@ private: | |||
| 87 | 91 | ||
| 88 | // SVC callback | 92 | // SVC callback |
| 89 | u32 svc_swi{}; | 93 | u32 svc_swi{}; |
| 90 | |||
| 91 | // Debug restart address | ||
| 92 | u64 breakpoint_pc{}; | ||
| 93 | }; | 94 | }; |
| 94 | 95 | ||
| 95 | } // namespace Core | 96 | } // namespace Core |