diff options
| author | 2019-11-28 11:43:17 -0500 | |
|---|---|---|
| committer | 2019-11-28 11:43:17 -0500 | |
| commit | e3ee017e91ef4d713f1af8cb60c5157e40d43f18 (patch) | |
| tree | e0a5b47cac1d548599b8ceba7f71b40746fe6b48 /src/core/arm | |
| parent | Merge pull request #3171 from lioncash/internal-link (diff) | |
| parent | core/memory; Migrate over SetCurrentPageTable() to the Memory class (diff) | |
| download | yuzu-e3ee017e91ef4d713f1af8cb60c5157e40d43f18.tar.gz yuzu-e3ee017e91ef4d713f1af8cb60c5157e40d43f18.tar.xz yuzu-e3ee017e91ef4d713f1af8cb60c5157e40d43f18.zip | |
Merge pull request #3169 from lioncash/memory
core/memory: Deglobalize memory management code
Diffstat (limited to 'src/core/arm')
| -rw-r--r-- | src/core/arm/arm_interface.cpp | 27 | ||||
| -rw-r--r-- | src/core/arm/arm_interface.h | 8 | ||||
| -rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic.cpp | 48 | ||||
| -rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic.h | 8 | ||||
| -rw-r--r-- | src/core/arm/unicorn/arm_unicorn.cpp | 2 | ||||
| -rw-r--r-- | src/core/arm/unicorn/arm_unicorn.h | 1 |
6 files changed, 53 insertions, 41 deletions
diff --git a/src/core/arm/arm_interface.cpp b/src/core/arm/arm_interface.cpp index 372612c9b..7e846ddd5 100644 --- a/src/core/arm/arm_interface.cpp +++ b/src/core/arm/arm_interface.cpp | |||
| @@ -13,7 +13,6 @@ | |||
| 13 | #include "core/memory.h" | 13 | #include "core/memory.h" |
| 14 | 14 | ||
| 15 | namespace Core { | 15 | namespace Core { |
| 16 | |||
| 17 | namespace { | 16 | namespace { |
| 18 | 17 | ||
| 19 | constexpr u64 ELF_DYNAMIC_TAG_NULL = 0; | 18 | constexpr u64 ELF_DYNAMIC_TAG_NULL = 0; |
| @@ -61,15 +60,15 @@ static_assert(sizeof(ELFSymbol) == 0x18, "ELFSymbol has incorrect size."); | |||
| 61 | 60 | ||
| 62 | using Symbols = std::vector<std::pair<ELFSymbol, std::string>>; | 61 | using Symbols = std::vector<std::pair<ELFSymbol, std::string>>; |
| 63 | 62 | ||
| 64 | Symbols GetSymbols(VAddr text_offset) { | 63 | Symbols GetSymbols(VAddr text_offset, Memory::Memory& memory) { |
| 65 | const auto mod_offset = text_offset + Memory::Read32(text_offset + 4); | 64 | const auto mod_offset = text_offset + memory.Read32(text_offset + 4); |
| 66 | 65 | ||
| 67 | if (mod_offset < text_offset || (mod_offset & 0b11) != 0 || | 66 | if (mod_offset < text_offset || (mod_offset & 0b11) != 0 || |
| 68 | Memory::Read32(mod_offset) != Common::MakeMagic('M', 'O', 'D', '0')) { | 67 | memory.Read32(mod_offset) != Common::MakeMagic('M', 'O', 'D', '0')) { |
| 69 | return {}; | 68 | return {}; |
| 70 | } | 69 | } |
| 71 | 70 | ||
| 72 | const auto dynamic_offset = Memory::Read32(mod_offset + 0x4) + mod_offset; | 71 | const auto dynamic_offset = memory.Read32(mod_offset + 0x4) + mod_offset; |
| 73 | 72 | ||
| 74 | VAddr string_table_offset{}; | 73 | VAddr string_table_offset{}; |
| 75 | VAddr symbol_table_offset{}; | 74 | VAddr symbol_table_offset{}; |
| @@ -77,8 +76,8 @@ Symbols GetSymbols(VAddr text_offset) { | |||
| 77 | 76 | ||
| 78 | VAddr dynamic_index = dynamic_offset; | 77 | VAddr dynamic_index = dynamic_offset; |
| 79 | while (true) { | 78 | while (true) { |
| 80 | const auto tag = Memory::Read64(dynamic_index); | 79 | const u64 tag = memory.Read64(dynamic_index); |
| 81 | const auto value = Memory::Read64(dynamic_index + 0x8); | 80 | const u64 value = memory.Read64(dynamic_index + 0x8); |
| 82 | dynamic_index += 0x10; | 81 | dynamic_index += 0x10; |
| 83 | 82 | ||
| 84 | if (tag == ELF_DYNAMIC_TAG_NULL) { | 83 | if (tag == ELF_DYNAMIC_TAG_NULL) { |
| @@ -106,11 +105,11 @@ Symbols GetSymbols(VAddr text_offset) { | |||
| 106 | VAddr symbol_index = symbol_table_address; | 105 | VAddr symbol_index = symbol_table_address; |
| 107 | while (symbol_index < string_table_address) { | 106 | while (symbol_index < string_table_address) { |
| 108 | ELFSymbol symbol{}; | 107 | ELFSymbol symbol{}; |
| 109 | Memory::ReadBlock(symbol_index, &symbol, sizeof(ELFSymbol)); | 108 | memory.ReadBlock(symbol_index, &symbol, sizeof(ELFSymbol)); |
| 110 | 109 | ||
| 111 | VAddr string_offset = string_table_address + symbol.name_index; | 110 | VAddr string_offset = string_table_address + symbol.name_index; |
| 112 | std::string name; | 111 | std::string name; |
| 113 | for (u8 c = Memory::Read8(string_offset); c != 0; c = Memory::Read8(++string_offset)) { | 112 | for (u8 c = memory.Read8(string_offset); c != 0; c = memory.Read8(++string_offset)) { |
| 114 | name += static_cast<char>(c); | 113 | name += static_cast<char>(c); |
| 115 | } | 114 | } |
| 116 | 115 | ||
| @@ -142,28 +141,28 @@ constexpr u64 SEGMENT_BASE = 0x7100000000ull; | |||
| 142 | 141 | ||
| 143 | std::vector<ARM_Interface::BacktraceEntry> ARM_Interface::GetBacktrace() const { | 142 | std::vector<ARM_Interface::BacktraceEntry> ARM_Interface::GetBacktrace() const { |
| 144 | std::vector<BacktraceEntry> out; | 143 | std::vector<BacktraceEntry> out; |
| 144 | auto& memory = system.Memory(); | ||
| 145 | 145 | ||
| 146 | auto fp = GetReg(29); | 146 | auto fp = GetReg(29); |
| 147 | auto lr = GetReg(30); | 147 | auto lr = GetReg(30); |
| 148 | |||
| 149 | while (true) { | 148 | while (true) { |
| 150 | out.push_back({"", 0, lr, 0}); | 149 | out.push_back({"", 0, lr, 0}); |
| 151 | if (!fp) { | 150 | if (!fp) { |
| 152 | break; | 151 | break; |
| 153 | } | 152 | } |
| 154 | lr = Memory::Read64(fp + 8) - 4; | 153 | lr = memory.Read64(fp + 8) - 4; |
| 155 | fp = Memory::Read64(fp); | 154 | fp = memory.Read64(fp); |
| 156 | } | 155 | } |
| 157 | 156 | ||
| 158 | std::map<VAddr, std::string> modules; | 157 | std::map<VAddr, std::string> modules; |
| 159 | auto& loader{System::GetInstance().GetAppLoader()}; | 158 | auto& loader{system.GetAppLoader()}; |
| 160 | if (loader.ReadNSOModules(modules) != Loader::ResultStatus::Success) { | 159 | if (loader.ReadNSOModules(modules) != Loader::ResultStatus::Success) { |
| 161 | return {}; | 160 | return {}; |
| 162 | } | 161 | } |
| 163 | 162 | ||
| 164 | std::map<std::string, Symbols> symbols; | 163 | std::map<std::string, Symbols> symbols; |
| 165 | for (const auto& module : modules) { | 164 | for (const auto& module : modules) { |
| 166 | symbols.insert_or_assign(module.second, GetSymbols(module.first)); | 165 | symbols.insert_or_assign(module.second, GetSymbols(module.first, memory)); |
| 167 | } | 166 | } |
| 168 | 167 | ||
| 169 | for (auto& entry : out) { | 168 | for (auto& entry : out) { |
diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h index 45e94e625..47b964eb7 100644 --- a/src/core/arm/arm_interface.h +++ b/src/core/arm/arm_interface.h | |||
| @@ -17,11 +17,13 @@ enum class VMAPermission : u8; | |||
| 17 | } | 17 | } |
| 18 | 18 | ||
| 19 | namespace Core { | 19 | namespace Core { |
| 20 | class System; | ||
| 20 | 21 | ||
| 21 | /// Generic ARMv8 CPU interface | 22 | /// Generic ARMv8 CPU interface |
| 22 | class ARM_Interface : NonCopyable { | 23 | class ARM_Interface : NonCopyable { |
| 23 | public: | 24 | public: |
| 24 | virtual ~ARM_Interface() {} | 25 | explicit ARM_Interface(System& system_) : system{system_} {} |
| 26 | virtual ~ARM_Interface() = default; | ||
| 25 | 27 | ||
| 26 | struct ThreadContext { | 28 | struct ThreadContext { |
| 27 | std::array<u64, 31> cpu_registers; | 29 | std::array<u64, 31> cpu_registers; |
| @@ -163,6 +165,10 @@ public: | |||
| 163 | /// fp+0 : pointer to previous frame record | 165 | /// fp+0 : pointer to previous frame record |
| 164 | /// fp+8 : value of lr for frame | 166 | /// fp+8 : value of lr for frame |
| 165 | void LogBacktrace() const; | 167 | void LogBacktrace() const; |
| 168 | |||
| 169 | protected: | ||
| 170 | /// System context that this ARM interface is running under. | ||
| 171 | System& system; | ||
| 166 | }; | 172 | }; |
| 167 | 173 | ||
| 168 | } // namespace Core | 174 | } // namespace Core |
diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp index a0705b2b8..f8c7f0efd 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic.cpp | |||
| @@ -28,36 +28,38 @@ public: | |||
| 28 | explicit ARM_Dynarmic_Callbacks(ARM_Dynarmic& parent) : parent(parent) {} | 28 | explicit ARM_Dynarmic_Callbacks(ARM_Dynarmic& parent) : parent(parent) {} |
| 29 | 29 | ||
| 30 | u8 MemoryRead8(u64 vaddr) override { | 30 | u8 MemoryRead8(u64 vaddr) override { |
| 31 | return Memory::Read8(vaddr); | 31 | return parent.system.Memory().Read8(vaddr); |
| 32 | } | 32 | } |
| 33 | u16 MemoryRead16(u64 vaddr) override { | 33 | u16 MemoryRead16(u64 vaddr) override { |
| 34 | return Memory::Read16(vaddr); | 34 | return parent.system.Memory().Read16(vaddr); |
| 35 | } | 35 | } |
| 36 | u32 MemoryRead32(u64 vaddr) override { | 36 | u32 MemoryRead32(u64 vaddr) override { |
| 37 | return Memory::Read32(vaddr); | 37 | return parent.system.Memory().Read32(vaddr); |
| 38 | } | 38 | } |
| 39 | u64 MemoryRead64(u64 vaddr) override { | 39 | u64 MemoryRead64(u64 vaddr) override { |
| 40 | return Memory::Read64(vaddr); | 40 | return parent.system.Memory().Read64(vaddr); |
| 41 | } | 41 | } |
| 42 | Vector MemoryRead128(u64 vaddr) override { | 42 | Vector MemoryRead128(u64 vaddr) override { |
| 43 | return {Memory::Read64(vaddr), Memory::Read64(vaddr + 8)}; | 43 | auto& memory = parent.system.Memory(); |
| 44 | return {memory.Read64(vaddr), memory.Read64(vaddr + 8)}; | ||
| 44 | } | 45 | } |
| 45 | 46 | ||
| 46 | void MemoryWrite8(u64 vaddr, u8 value) override { | 47 | void MemoryWrite8(u64 vaddr, u8 value) override { |
| 47 | Memory::Write8(vaddr, value); | 48 | parent.system.Memory().Write8(vaddr, value); |
| 48 | } | 49 | } |
| 49 | void MemoryWrite16(u64 vaddr, u16 value) override { | 50 | void MemoryWrite16(u64 vaddr, u16 value) override { |
| 50 | Memory::Write16(vaddr, value); | 51 | parent.system.Memory().Write16(vaddr, value); |
| 51 | } | 52 | } |
| 52 | void MemoryWrite32(u64 vaddr, u32 value) override { | 53 | void MemoryWrite32(u64 vaddr, u32 value) override { |
| 53 | Memory::Write32(vaddr, value); | 54 | parent.system.Memory().Write32(vaddr, value); |
| 54 | } | 55 | } |
| 55 | void MemoryWrite64(u64 vaddr, u64 value) override { | 56 | void MemoryWrite64(u64 vaddr, u64 value) override { |
| 56 | Memory::Write64(vaddr, value); | 57 | parent.system.Memory().Write64(vaddr, value); |
| 57 | } | 58 | } |
| 58 | void MemoryWrite128(u64 vaddr, Vector value) override { | 59 | void MemoryWrite128(u64 vaddr, Vector value) override { |
| 59 | Memory::Write64(vaddr, value[0]); | 60 | auto& memory = parent.system.Memory(); |
| 60 | Memory::Write64(vaddr + 8, value[1]); | 61 | memory.Write64(vaddr, value[0]); |
| 62 | memory.Write64(vaddr + 8, value[1]); | ||
| 61 | } | 63 | } |
| 62 | 64 | ||
| 63 | void InterpreterFallback(u64 pc, std::size_t num_instructions) override { | 65 | void InterpreterFallback(u64 pc, std::size_t num_instructions) override { |
| @@ -171,9 +173,10 @@ void ARM_Dynarmic::Step() { | |||
| 171 | 173 | ||
| 172 | ARM_Dynarmic::ARM_Dynarmic(System& system, ExclusiveMonitor& exclusive_monitor, | 174 | ARM_Dynarmic::ARM_Dynarmic(System& system, ExclusiveMonitor& exclusive_monitor, |
| 173 | std::size_t core_index) | 175 | std::size_t core_index) |
| 174 | : cb(std::make_unique<ARM_Dynarmic_Callbacks>(*this)), inner_unicorn{system}, | 176 | : ARM_Interface{system}, |
| 175 | core_index{core_index}, system{system}, | 177 | cb(std::make_unique<ARM_Dynarmic_Callbacks>(*this)), inner_unicorn{system}, |
| 176 | exclusive_monitor{dynamic_cast<DynarmicExclusiveMonitor&>(exclusive_monitor)} {} | 178 | core_index{core_index}, exclusive_monitor{ |
| 179 | dynamic_cast<DynarmicExclusiveMonitor&>(exclusive_monitor)} {} | ||
| 177 | 180 | ||
| 178 | ARM_Dynarmic::~ARM_Dynarmic() = default; | 181 | ARM_Dynarmic::~ARM_Dynarmic() = default; |
| 179 | 182 | ||
| @@ -264,7 +267,9 @@ void ARM_Dynarmic::PageTableChanged(Common::PageTable& page_table, | |||
| 264 | jit = MakeJit(page_table, new_address_space_size_in_bits); | 267 | jit = MakeJit(page_table, new_address_space_size_in_bits); |
| 265 | } | 268 | } |
| 266 | 269 | ||
| 267 | DynarmicExclusiveMonitor::DynarmicExclusiveMonitor(std::size_t core_count) : monitor(core_count) {} | 270 | DynarmicExclusiveMonitor::DynarmicExclusiveMonitor(Memory::Memory& memory_, std::size_t core_count) |
| 271 | : monitor(core_count), memory{memory_} {} | ||
| 272 | |||
| 268 | DynarmicExclusiveMonitor::~DynarmicExclusiveMonitor() = default; | 273 | DynarmicExclusiveMonitor::~DynarmicExclusiveMonitor() = default; |
| 269 | 274 | ||
| 270 | void DynarmicExclusiveMonitor::SetExclusive(std::size_t core_index, VAddr addr) { | 275 | void DynarmicExclusiveMonitor::SetExclusive(std::size_t core_index, VAddr addr) { |
| @@ -277,29 +282,28 @@ void DynarmicExclusiveMonitor::ClearExclusive() { | |||
| 277 | } | 282 | } |
| 278 | 283 | ||
| 279 | bool DynarmicExclusiveMonitor::ExclusiveWrite8(std::size_t core_index, VAddr vaddr, u8 value) { | 284 | bool DynarmicExclusiveMonitor::ExclusiveWrite8(std::size_t core_index, VAddr vaddr, u8 value) { |
| 280 | return monitor.DoExclusiveOperation(core_index, vaddr, 1, | 285 | return monitor.DoExclusiveOperation(core_index, vaddr, 1, [&] { memory.Write8(vaddr, value); }); |
| 281 | [&] { Memory::Write8(vaddr, value); }); | ||
| 282 | } | 286 | } |
| 283 | 287 | ||
| 284 | bool DynarmicExclusiveMonitor::ExclusiveWrite16(std::size_t core_index, VAddr vaddr, u16 value) { | 288 | bool DynarmicExclusiveMonitor::ExclusiveWrite16(std::size_t core_index, VAddr vaddr, u16 value) { |
| 285 | return monitor.DoExclusiveOperation(core_index, vaddr, 2, | 289 | return monitor.DoExclusiveOperation(core_index, vaddr, 2, |
| 286 | [&] { Memory::Write16(vaddr, value); }); | 290 | [&] { memory.Write16(vaddr, value); }); |
| 287 | } | 291 | } |
| 288 | 292 | ||
| 289 | bool DynarmicExclusiveMonitor::ExclusiveWrite32(std::size_t core_index, VAddr vaddr, u32 value) { | 293 | bool DynarmicExclusiveMonitor::ExclusiveWrite32(std::size_t core_index, VAddr vaddr, u32 value) { |
| 290 | return monitor.DoExclusiveOperation(core_index, vaddr, 4, | 294 | return monitor.DoExclusiveOperation(core_index, vaddr, 4, |
| 291 | [&] { Memory::Write32(vaddr, value); }); | 295 | [&] { memory.Write32(vaddr, value); }); |
| 292 | } | 296 | } |
| 293 | 297 | ||
| 294 | bool DynarmicExclusiveMonitor::ExclusiveWrite64(std::size_t core_index, VAddr vaddr, u64 value) { | 298 | bool DynarmicExclusiveMonitor::ExclusiveWrite64(std::size_t core_index, VAddr vaddr, u64 value) { |
| 295 | return monitor.DoExclusiveOperation(core_index, vaddr, 8, | 299 | return monitor.DoExclusiveOperation(core_index, vaddr, 8, |
| 296 | [&] { Memory::Write64(vaddr, value); }); | 300 | [&] { memory.Write64(vaddr, value); }); |
| 297 | } | 301 | } |
| 298 | 302 | ||
| 299 | bool DynarmicExclusiveMonitor::ExclusiveWrite128(std::size_t core_index, VAddr vaddr, u128 value) { | 303 | bool DynarmicExclusiveMonitor::ExclusiveWrite128(std::size_t core_index, VAddr vaddr, u128 value) { |
| 300 | return monitor.DoExclusiveOperation(core_index, vaddr, 16, [&] { | 304 | return monitor.DoExclusiveOperation(core_index, vaddr, 16, [&] { |
| 301 | Memory::Write64(vaddr + 0, value[0]); | 305 | memory.Write64(vaddr + 0, value[0]); |
| 302 | Memory::Write64(vaddr + 8, value[1]); | 306 | memory.Write64(vaddr + 8, value[1]); |
| 303 | }); | 307 | }); |
| 304 | } | 308 | } |
| 305 | 309 | ||
diff --git a/src/core/arm/dynarmic/arm_dynarmic.h b/src/core/arm/dynarmic/arm_dynarmic.h index 504d46c68..9cd475cfb 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.h +++ b/src/core/arm/dynarmic/arm_dynarmic.h | |||
| @@ -12,6 +12,10 @@ | |||
| 12 | #include "core/arm/exclusive_monitor.h" | 12 | #include "core/arm/exclusive_monitor.h" |
| 13 | #include "core/arm/unicorn/arm_unicorn.h" | 13 | #include "core/arm/unicorn/arm_unicorn.h" |
| 14 | 14 | ||
| 15 | namespace Memory { | ||
| 16 | class Memory; | ||
| 17 | } | ||
| 18 | |||
| 15 | namespace Core { | 19 | namespace Core { |
| 16 | 20 | ||
| 17 | class ARM_Dynarmic_Callbacks; | 21 | class ARM_Dynarmic_Callbacks; |
| @@ -58,13 +62,12 @@ private: | |||
| 58 | ARM_Unicorn inner_unicorn; | 62 | ARM_Unicorn inner_unicorn; |
| 59 | 63 | ||
| 60 | std::size_t core_index; | 64 | std::size_t core_index; |
| 61 | System& system; | ||
| 62 | DynarmicExclusiveMonitor& exclusive_monitor; | 65 | DynarmicExclusiveMonitor& exclusive_monitor; |
| 63 | }; | 66 | }; |
| 64 | 67 | ||
| 65 | class DynarmicExclusiveMonitor final : public ExclusiveMonitor { | 68 | class DynarmicExclusiveMonitor final : public ExclusiveMonitor { |
| 66 | public: | 69 | public: |
| 67 | explicit DynarmicExclusiveMonitor(std::size_t core_count); | 70 | explicit DynarmicExclusiveMonitor(Memory::Memory& memory_, std::size_t core_count); |
| 68 | ~DynarmicExclusiveMonitor() override; | 71 | ~DynarmicExclusiveMonitor() override; |
| 69 | 72 | ||
| 70 | void SetExclusive(std::size_t core_index, VAddr addr) override; | 73 | void SetExclusive(std::size_t core_index, VAddr addr) override; |
| @@ -79,6 +82,7 @@ public: | |||
| 79 | private: | 82 | private: |
| 80 | friend class ARM_Dynarmic; | 83 | friend class ARM_Dynarmic; |
| 81 | Dynarmic::A64::ExclusiveMonitor monitor; | 84 | Dynarmic::A64::ExclusiveMonitor monitor; |
| 85 | Memory::Memory& memory; | ||
| 82 | }; | 86 | }; |
| 83 | 87 | ||
| 84 | } // namespace Core | 88 | } // namespace Core |
diff --git a/src/core/arm/unicorn/arm_unicorn.cpp b/src/core/arm/unicorn/arm_unicorn.cpp index 9698172db..48182c99a 100644 --- a/src/core/arm/unicorn/arm_unicorn.cpp +++ b/src/core/arm/unicorn/arm_unicorn.cpp | |||
| @@ -60,7 +60,7 @@ static bool UnmappedMemoryHook(uc_engine* uc, uc_mem_type type, u64 addr, int si | |||
| 60 | return false; | 60 | return false; |
| 61 | } | 61 | } |
| 62 | 62 | ||
| 63 | ARM_Unicorn::ARM_Unicorn(System& system) : system{system} { | 63 | ARM_Unicorn::ARM_Unicorn(System& system) : ARM_Interface{system} { |
| 64 | CHECKED(uc_open(UC_ARCH_ARM64, UC_MODE_ARM, &uc)); | 64 | CHECKED(uc_open(UC_ARCH_ARM64, UC_MODE_ARM, &uc)); |
| 65 | 65 | ||
| 66 | auto fpv = 3 << 20; | 66 | auto fpv = 3 << 20; |
diff --git a/src/core/arm/unicorn/arm_unicorn.h b/src/core/arm/unicorn/arm_unicorn.h index b39426ea0..3c5b155f9 100644 --- a/src/core/arm/unicorn/arm_unicorn.h +++ b/src/core/arm/unicorn/arm_unicorn.h | |||
| @@ -45,7 +45,6 @@ private: | |||
| 45 | static void InterruptHook(uc_engine* uc, u32 int_no, void* user_data); | 45 | static void InterruptHook(uc_engine* uc, u32 int_no, void* user_data); |
| 46 | 46 | ||
| 47 | uc_engine* uc{}; | 47 | uc_engine* uc{}; |
| 48 | System& system; | ||
| 49 | GDBStub::BreakpointAddress last_bkpt{}; | 48 | GDBStub::BreakpointAddress last_bkpt{}; |
| 50 | bool last_bkpt_hit = false; | 49 | bool last_bkpt_hit = false; |
| 51 | }; | 50 | }; |