|
|
@@ -175,9 +175,10 @@ struct Breakpoint {
|
|
|
u64 len;
|
|
|
};
|
|
|
|
|
|
-std::map<u64, Breakpoint> breakpoints_execute;
|
|
|
-std::map<u64, Breakpoint> breakpoints_read;
|
|
|
-std::map<u64, Breakpoint> breakpoints_write;
|
|
|
+using BreakpointMap = std::map<VAddr, Breakpoint>;
|
|
|
+BreakpointMap breakpoints_execute;
|
|
|
+BreakpointMap breakpoints_read;
|
|
|
+BreakpointMap breakpoints_write;
|
|
|
|
|
|
struct Module {
|
|
|
std::string name;
|
|
|
@@ -419,11 +420,11 @@ static u8 CalculateChecksum(const u8* buffer, size_t length) {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Get the list of breakpoints for a given breakpoint type.
|
|
|
+ * Get the map of breakpoints for a given breakpoint type.
|
|
|
*
|
|
|
- * @param type Type of breakpoint list.
|
|
|
+ * @param type Type of breakpoint map.
|
|
|
*/
|
|
|
-static std::map<u64, Breakpoint>& GetBreakpointList(BreakpointType type) {
|
|
|
+static BreakpointMap& GetBreakpointMap(BreakpointType type) {
|
|
|
switch (type) {
|
|
|
case BreakpointType::Execute:
|
|
|
return breakpoints_execute;
|
|
|
@@ -443,19 +444,21 @@ static std::map<u64, Breakpoint>& GetBreakpointList(BreakpointType type) {
|
|
|
* @param addr Address of breakpoint.
|
|
|
*/
|
|
|
static void RemoveBreakpoint(BreakpointType type, VAddr addr) {
|
|
|
- std::map<u64, Breakpoint>& p = GetBreakpointList(type);
|
|
|
+ BreakpointMap& p = GetBreakpointMap(type);
|
|
|
|
|
|
- auto bp = p.find(static_cast<u64>(addr));
|
|
|
- if (bp != p.end()) {
|
|
|
- LOG_DEBUG(Debug_GDBStub, "gdb: removed a breakpoint: {:016X} bytes at {:016X} of type {}",
|
|
|
- bp->second.len, bp->second.addr, static_cast<int>(type));
|
|
|
- p.erase(static_cast<u64>(addr));
|
|
|
+ const auto bp = p.find(addr);
|
|
|
+ if (bp == p.end()) {
|
|
|
+ return;
|
|
|
}
|
|
|
+
|
|
|
+ LOG_DEBUG(Debug_GDBStub, "gdb: removed a breakpoint: {:016X} bytes at {:016X} of type {}",
|
|
|
+ bp->second.len, bp->second.addr, static_cast<int>(type));
|
|
|
+ p.erase(addr);
|
|
|
}
|
|
|
|
|
|
BreakpointAddress GetNextBreakpointFromAddress(VAddr addr, BreakpointType type) {
|
|
|
- std::map<u64, Breakpoint>& p = GetBreakpointList(type);
|
|
|
- auto next_breakpoint = p.lower_bound(static_cast<u64>(addr));
|
|
|
+ const BreakpointMap& p = GetBreakpointMap(type);
|
|
|
+ const auto next_breakpoint = p.lower_bound(addr);
|
|
|
BreakpointAddress breakpoint;
|
|
|
|
|
|
if (next_breakpoint != p.end()) {
|
|
|
@@ -474,31 +477,33 @@ bool CheckBreakpoint(VAddr addr, BreakpointType type) {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
- std::map<u64, Breakpoint>& p = GetBreakpointList(type);
|
|
|
+ const BreakpointMap& p = GetBreakpointMap(type);
|
|
|
+ const auto bp = p.find(addr);
|
|
|
+
|
|
|
+ if (bp == p.end()) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
|
|
|
- auto bp = p.find(static_cast<u64>(addr));
|
|
|
- if (bp != p.end()) {
|
|
|
- u64 len = bp->second.len;
|
|
|
+ u64 len = bp->second.len;
|
|
|
|
|
|
- // IDA Pro defaults to 4-byte breakpoints for all non-hardware breakpoints
|
|
|
- // no matter if it's a 4-byte or 2-byte instruction. When you execute a
|
|
|
- // Thumb instruction with a 4-byte breakpoint set, it will set a breakpoint on
|
|
|
- // two instructions instead of the single instruction you placed the breakpoint
|
|
|
- // on. So, as a way to make sure that execution breakpoints are only breaking
|
|
|
- // on the instruction that was specified, set the length of an execution
|
|
|
- // breakpoint to 1. This should be fine since the CPU should never begin executing
|
|
|
- // an instruction anywhere except the beginning of the instruction.
|
|
|
- if (type == BreakpointType::Execute) {
|
|
|
- len = 1;
|
|
|
- }
|
|
|
+ // IDA Pro defaults to 4-byte breakpoints for all non-hardware breakpoints
|
|
|
+ // no matter if it's a 4-byte or 2-byte instruction. When you execute a
|
|
|
+ // Thumb instruction with a 4-byte breakpoint set, it will set a breakpoint on
|
|
|
+ // two instructions instead of the single instruction you placed the breakpoint
|
|
|
+ // on. So, as a way to make sure that execution breakpoints are only breaking
|
|
|
+ // on the instruction that was specified, set the length of an execution
|
|
|
+ // breakpoint to 1. This should be fine since the CPU should never begin executing
|
|
|
+ // an instruction anywhere except the beginning of the instruction.
|
|
|
+ if (type == BreakpointType::Execute) {
|
|
|
+ len = 1;
|
|
|
+ }
|
|
|
|
|
|
- if (bp->second.active && (addr >= bp->second.addr && addr < bp->second.addr + len)) {
|
|
|
- LOG_DEBUG(Debug_GDBStub,
|
|
|
- "Found breakpoint type {} @ {:016X}, range: {:016X}"
|
|
|
- " - {:016X} ({:X} bytes)",
|
|
|
- static_cast<int>(type), addr, bp->second.addr, bp->second.addr + len, len);
|
|
|
- return true;
|
|
|
- }
|
|
|
+ if (bp->second.active && (addr >= bp->second.addr && addr < bp->second.addr + len)) {
|
|
|
+ LOG_DEBUG(Debug_GDBStub,
|
|
|
+ "Found breakpoint type {} @ {:016X}, range: {:016X}"
|
|
|
+ " - {:016X} ({:X} bytes)",
|
|
|
+ static_cast<int>(type), addr, bp->second.addr, bp->second.addr + len, len);
|
|
|
+ return true;
|
|
|
}
|
|
|
|
|
|
return false;
|
|
|
@@ -977,7 +982,7 @@ static void Continue() {
|
|
|
* @param len Length of breakpoint.
|
|
|
*/
|
|
|
static bool CommitBreakpoint(BreakpointType type, VAddr addr, u64 len) {
|
|
|
- std::map<u64, Breakpoint>& p = GetBreakpointList(type);
|
|
|
+ BreakpointMap& p = GetBreakpointMap(type);
|
|
|
|
|
|
Breakpoint breakpoint;
|
|
|
breakpoint.active = true;
|