summaryrefslogtreecommitdiff
path: root/src/core/gdbstub/gdbstub.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/gdbstub/gdbstub.cpp')
-rw-r--r--src/core/gdbstub/gdbstub.cpp79
1 files changed, 42 insertions, 37 deletions
diff --git a/src/core/gdbstub/gdbstub.cpp b/src/core/gdbstub/gdbstub.cpp
index 22ea53e22..884e64e99 100644
--- a/src/core/gdbstub/gdbstub.cpp
+++ b/src/core/gdbstub/gdbstub.cpp
@@ -175,9 +175,10 @@ struct Breakpoint {
175 u64 len; 175 u64 len;
176}; 176};
177 177
178std::map<u64, Breakpoint> breakpoints_execute; 178using BreakpointMap = std::map<VAddr, Breakpoint>;
179std::map<u64, Breakpoint> breakpoints_read; 179BreakpointMap breakpoints_execute;
180std::map<u64, Breakpoint> breakpoints_write; 180BreakpointMap breakpoints_read;
181BreakpointMap breakpoints_write;
181 182
182struct Module { 183struct Module {
183 std::string name; 184 std::string name;
@@ -419,11 +420,11 @@ static u8 CalculateChecksum(const u8* buffer, size_t length) {
419} 420}
420 421
421/** 422/**
422 * Get the list of breakpoints for a given breakpoint type. 423 * Get the map of breakpoints for a given breakpoint type.
423 * 424 *
424 * @param type Type of breakpoint list. 425 * @param type Type of breakpoint map.
425 */ 426 */
426static std::map<u64, Breakpoint>& GetBreakpointList(BreakpointType type) { 427static BreakpointMap& GetBreakpointMap(BreakpointType type) {
427 switch (type) { 428 switch (type) {
428 case BreakpointType::Execute: 429 case BreakpointType::Execute:
429 return breakpoints_execute; 430 return breakpoints_execute;
@@ -443,19 +444,21 @@ static std::map<u64, Breakpoint>& GetBreakpointList(BreakpointType type) {
443 * @param addr Address of breakpoint. 444 * @param addr Address of breakpoint.
444 */ 445 */
445static void RemoveBreakpoint(BreakpointType type, VAddr addr) { 446static void RemoveBreakpoint(BreakpointType type, VAddr addr) {
446 std::map<u64, Breakpoint>& p = GetBreakpointList(type); 447 BreakpointMap& p = GetBreakpointMap(type);
447 448
448 auto bp = p.find(static_cast<u64>(addr)); 449 const auto bp = p.find(addr);
449 if (bp != p.end()) { 450 if (bp == p.end()) {
450 LOG_DEBUG(Debug_GDBStub, "gdb: removed a breakpoint: {:016X} bytes at {:016X} of type {}", 451 return;
451 bp->second.len, bp->second.addr, static_cast<int>(type));
452 p.erase(static_cast<u64>(addr));
453 } 452 }
453
454 LOG_DEBUG(Debug_GDBStub, "gdb: removed a breakpoint: {:016X} bytes at {:016X} of type {}",
455 bp->second.len, bp->second.addr, static_cast<int>(type));
456 p.erase(addr);
454} 457}
455 458
456BreakpointAddress GetNextBreakpointFromAddress(VAddr addr, BreakpointType type) { 459BreakpointAddress GetNextBreakpointFromAddress(VAddr addr, BreakpointType type) {
457 std::map<u64, Breakpoint>& p = GetBreakpointList(type); 460 const BreakpointMap& p = GetBreakpointMap(type);
458 auto next_breakpoint = p.lower_bound(static_cast<u64>(addr)); 461 const auto next_breakpoint = p.lower_bound(addr);
459 BreakpointAddress breakpoint; 462 BreakpointAddress breakpoint;
460 463
461 if (next_breakpoint != p.end()) { 464 if (next_breakpoint != p.end()) {
@@ -474,31 +477,33 @@ bool CheckBreakpoint(VAddr addr, BreakpointType type) {
474 return false; 477 return false;
475 } 478 }
476 479
477 std::map<u64, Breakpoint>& p = GetBreakpointList(type); 480 const BreakpointMap& p = GetBreakpointMap(type);
481 const auto bp = p.find(addr);
482
483 if (bp == p.end()) {
484 return false;
485 }
478 486
479 auto bp = p.find(static_cast<u64>(addr)); 487 u64 len = bp->second.len;
480 if (bp != p.end()) {
481 u64 len = bp->second.len;
482 488
483 // IDA Pro defaults to 4-byte breakpoints for all non-hardware breakpoints 489 // IDA Pro defaults to 4-byte breakpoints for all non-hardware breakpoints
484 // no matter if it's a 4-byte or 2-byte instruction. When you execute a 490 // no matter if it's a 4-byte or 2-byte instruction. When you execute a
485 // Thumb instruction with a 4-byte breakpoint set, it will set a breakpoint on 491 // Thumb instruction with a 4-byte breakpoint set, it will set a breakpoint on
486 // two instructions instead of the single instruction you placed the breakpoint 492 // two instructions instead of the single instruction you placed the breakpoint
487 // on. So, as a way to make sure that execution breakpoints are only breaking 493 // on. So, as a way to make sure that execution breakpoints are only breaking
488 // on the instruction that was specified, set the length of an execution 494 // on the instruction that was specified, set the length of an execution
489 // breakpoint to 1. This should be fine since the CPU should never begin executing 495 // breakpoint to 1. This should be fine since the CPU should never begin executing
490 // an instruction anywhere except the beginning of the instruction. 496 // an instruction anywhere except the beginning of the instruction.
491 if (type == BreakpointType::Execute) { 497 if (type == BreakpointType::Execute) {
492 len = 1; 498 len = 1;
493 } 499 }
494 500
495 if (bp->second.active && (addr >= bp->second.addr && addr < bp->second.addr + len)) { 501 if (bp->second.active && (addr >= bp->second.addr && addr < bp->second.addr + len)) {
496 LOG_DEBUG(Debug_GDBStub, 502 LOG_DEBUG(Debug_GDBStub,
497 "Found breakpoint type {} @ {:016X}, range: {:016X}" 503 "Found breakpoint type {} @ {:016X}, range: {:016X}"
498 " - {:016X} ({:X} bytes)", 504 " - {:016X} ({:X} bytes)",
499 static_cast<int>(type), addr, bp->second.addr, bp->second.addr + len, len); 505 static_cast<int>(type), addr, bp->second.addr, bp->second.addr + len, len);
500 return true; 506 return true;
501 }
502 } 507 }
503 508
504 return false; 509 return false;
@@ -977,7 +982,7 @@ static void Continue() {
977 * @param len Length of breakpoint. 982 * @param len Length of breakpoint.
978 */ 983 */
979static bool CommitBreakpoint(BreakpointType type, VAddr addr, u64 len) { 984static bool CommitBreakpoint(BreakpointType type, VAddr addr, u64 len) {
980 std::map<u64, Breakpoint>& p = GetBreakpointList(type); 985 BreakpointMap& p = GetBreakpointMap(type);
981 986
982 Breakpoint breakpoint; 987 Breakpoint breakpoint;
983 breakpoint.active = true; 988 breakpoint.active = true;