summaryrefslogtreecommitdiff
path: root/src/core/arm
diff options
context:
space:
mode:
authorGravatar Hedges2018-06-06 05:20:47 +0100
committerGravatar bunnei2018-06-06 00:20:47 -0400
commit39fb3e362cf71d0542a5807c97039cd474ef3716 (patch)
treee54ad38fba3c7b2b32e5e408e9e7eb8cb6ffe6b0 /src/core/arm
parentMerge pull request #516 from Subv/f2i_r (diff)
downloadyuzu-39fb3e362cf71d0542a5807c97039cd474ef3716.tar.gz
yuzu-39fb3e362cf71d0542a5807c97039cd474ef3716.tar.xz
yuzu-39fb3e362cf71d0542a5807c97039cd474ef3716.zip
GDB Stub Improvements (#508)
* GDB Stub should work now. * Applied clang-format. * Replaced htonll with swap64. * Tidy up.
Diffstat (limited to 'src/core/arm')
-rw-r--r--src/core/arm/unicorn/arm_unicorn.cpp38
-rw-r--r--src/core/arm/unicorn/arm_unicorn.h4
2 files changed, 41 insertions, 1 deletions
diff --git a/src/core/arm/unicorn/arm_unicorn.cpp b/src/core/arm/unicorn/arm_unicorn.cpp
index c0cc62f03..ce6c5616d 100644
--- a/src/core/arm/unicorn/arm_unicorn.cpp
+++ b/src/core/arm/unicorn/arm_unicorn.cpp
@@ -35,6 +35,17 @@ LoadDll LoadDll::g_load_dll;
35 } \ 35 } \
36 } while (0) 36 } while (0)
37 37
38static void CodeHook(uc_engine* uc, uint64_t address, uint32_t size, void* user_data) {
39 GDBStub::BreakpointAddress bkpt =
40 GDBStub::GetNextBreakpointFromAddress(address, GDBStub::BreakpointType::Execute);
41 if (GDBStub::IsMemoryBreak() ||
42 (bkpt.type != GDBStub::BreakpointType::None && address == bkpt.address)) {
43 auto core = static_cast<ARM_Unicorn*>(user_data);
44 core->RecordBreak(bkpt);
45 uc_emu_stop(uc);
46 }
47}
48
38static void InterruptHook(uc_engine* uc, u32 intNo, void* user_data) { 49static void InterruptHook(uc_engine* uc, u32 intNo, void* user_data) {
39 u32 esr{}; 50 u32 esr{};
40 CHECKED(uc_reg_read(uc, UC_ARM64_REG_ESR, &esr)); 51 CHECKED(uc_reg_read(uc, UC_ARM64_REG_ESR, &esr));
@@ -67,6 +78,10 @@ ARM_Unicorn::ARM_Unicorn() {
67 uc_hook hook{}; 78 uc_hook hook{};
68 CHECKED(uc_hook_add(uc, &hook, UC_HOOK_INTR, (void*)InterruptHook, this, 0, -1)); 79 CHECKED(uc_hook_add(uc, &hook, UC_HOOK_INTR, (void*)InterruptHook, this, 0, -1));
69 CHECKED(uc_hook_add(uc, &hook, UC_HOOK_MEM_INVALID, (void*)UnmappedMemoryHook, this, 0, -1)); 80 CHECKED(uc_hook_add(uc, &hook, UC_HOOK_MEM_INVALID, (void*)UnmappedMemoryHook, this, 0, -1));
81 if (GDBStub::IsServerEnabled()) {
82 CHECKED(uc_hook_add(uc, &hook, UC_HOOK_CODE, (void*)CodeHook, this, 0, -1));
83 last_bkpt_hit = false;
84 }
70} 85}
71 86
72ARM_Unicorn::~ARM_Unicorn() { 87ARM_Unicorn::~ARM_Unicorn() {
@@ -155,7 +170,11 @@ void ARM_Unicorn::SetTlsAddress(VAddr base) {
155} 170}
156 171
157void ARM_Unicorn::Run() { 172void ARM_Unicorn::Run() {
158 ExecuteInstructions(std::max(CoreTiming::GetDowncount(), 0)); 173 if (GDBStub::IsServerEnabled()) {
174 ExecuteInstructions(std::max(4000000, 0));
175 } else {
176 ExecuteInstructions(std::max(CoreTiming::GetDowncount(), 0));
177 }
159} 178}
160 179
161void ARM_Unicorn::Step() { 180void ARM_Unicorn::Step() {
@@ -168,6 +187,18 @@ void ARM_Unicorn::ExecuteInstructions(int num_instructions) {
168 MICROPROFILE_SCOPE(ARM_Jit); 187 MICROPROFILE_SCOPE(ARM_Jit);
169 CHECKED(uc_emu_start(uc, GetPC(), 1ULL << 63, 0, num_instructions)); 188 CHECKED(uc_emu_start(uc, GetPC(), 1ULL << 63, 0, num_instructions));
170 CoreTiming::AddTicks(num_instructions); 189 CoreTiming::AddTicks(num_instructions);
190 if (GDBStub::IsServerEnabled()) {
191 if (last_bkpt_hit) {
192 uc_reg_write(uc, UC_ARM64_REG_PC, &last_bkpt.address);
193 }
194 Kernel::Thread* thread = Kernel::GetCurrentThread();
195 SaveContext(thread->context);
196 if (last_bkpt_hit) {
197 last_bkpt_hit = false;
198 GDBStub::Break();
199 }
200 GDBStub::SendTrap(thread, 5);
201 }
171} 202}
172 203
173void ARM_Unicorn::SaveContext(ARM_Interface::ThreadContext& ctx) { 204void ARM_Unicorn::SaveContext(ARM_Interface::ThreadContext& ctx) {
@@ -233,3 +264,8 @@ void ARM_Unicorn::PrepareReschedule() {
233} 264}
234 265
235void ARM_Unicorn::ClearInstructionCache() {} 266void ARM_Unicorn::ClearInstructionCache() {}
267
268void ARM_Unicorn::RecordBreak(GDBStub::BreakpointAddress bkpt) {
269 last_bkpt = bkpt;
270 last_bkpt_hit = true;
271}
diff --git a/src/core/arm/unicorn/arm_unicorn.h b/src/core/arm/unicorn/arm_unicorn.h
index b99b58e4c..a482a2aa3 100644
--- a/src/core/arm/unicorn/arm_unicorn.h
+++ b/src/core/arm/unicorn/arm_unicorn.h
@@ -7,6 +7,7 @@
7#include <unicorn/unicorn.h> 7#include <unicorn/unicorn.h>
8#include "common/common_types.h" 8#include "common/common_types.h"
9#include "core/arm/arm_interface.h" 9#include "core/arm/arm_interface.h"
10#include "core/gdbstub/gdbstub.h"
10 11
11class ARM_Unicorn final : public ARM_Interface { 12class ARM_Unicorn final : public ARM_Interface {
12public: 13public:
@@ -35,7 +36,10 @@ public:
35 void Step() override; 36 void Step() override;
36 void ClearInstructionCache() override; 37 void ClearInstructionCache() override;
37 void PageTableChanged() override{}; 38 void PageTableChanged() override{};
39 void RecordBreak(GDBStub::BreakpointAddress bkpt);
38 40
39private: 41private:
40 uc_engine* uc{}; 42 uc_engine* uc{};
43 GDBStub::BreakpointAddress last_bkpt{};
44 bool last_bkpt_hit;
41}; 45};