Support watchpoints
This commit is contained in:
+96
-17
@@ -13,7 +13,9 @@ use tokio::{
|
||||
sync::{mpsc, oneshot},
|
||||
};
|
||||
|
||||
use crate::emulator::{DebugEvent, DebugStopReason, EmulatorClient, EmulatorCommand, SimId};
|
||||
use crate::emulator::{
|
||||
DebugEvent, DebugStopReason, EmulatorClient, EmulatorCommand, SimId, VBWatchpointType,
|
||||
};
|
||||
|
||||
mod registers;
|
||||
mod request;
|
||||
@@ -187,7 +189,7 @@ impl GdbConnection {
|
||||
}
|
||||
self.stop_reason = Some(reason);
|
||||
self.response()
|
||||
.write_str(debug_stop_reason_string(self.stop_reason))
|
||||
.write_str(&debug_stop_reason_string(self.stop_reason))
|
||||
}
|
||||
};
|
||||
Some(res)
|
||||
@@ -251,7 +253,7 @@ impl GdbConnection {
|
||||
bail!("debug process was killed");
|
||||
} else if req.match_str("?") {
|
||||
self.response()
|
||||
.write_str(debug_stop_reason_string(self.stop_reason))
|
||||
.write_str(&debug_stop_reason_string(self.stop_reason))
|
||||
} else if req.match_some_str(["c", "vCont;c:"]).is_some() {
|
||||
self.client
|
||||
.send_command(EmulatorCommand::DebugContinue(self.sim_id));
|
||||
@@ -329,18 +331,68 @@ impl GdbConnection {
|
||||
} else {
|
||||
self.response()
|
||||
}
|
||||
} else if req.match_str("Z0,") {
|
||||
if let Some(address) = req.match_hex() {
|
||||
self.client
|
||||
.send_command(EmulatorCommand::AddBreakpoint(self.sim_id, address));
|
||||
} else if req.match_str("Z") {
|
||||
let mut parse_request = || {
|
||||
let type_ = req.match_hex::<u8>()?;
|
||||
if !req.match_str(",") {
|
||||
return None;
|
||||
}
|
||||
let address = req.match_hex()?;
|
||||
if type_ == 0 || type_ == 1 {
|
||||
return Some(EmulatorCommand::AddBreakpoint(self.sim_id, address));
|
||||
}
|
||||
if !req.match_str(",") {
|
||||
return None;
|
||||
}
|
||||
let length = req.match_hex()?;
|
||||
let watch = match type_ {
|
||||
2 => VBWatchpointType::Write,
|
||||
3 => VBWatchpointType::Read,
|
||||
4 => VBWatchpointType::Access,
|
||||
_ => return None,
|
||||
};
|
||||
Some(EmulatorCommand::AddWatchpoint(
|
||||
self.sim_id,
|
||||
address,
|
||||
length,
|
||||
watch,
|
||||
))
|
||||
};
|
||||
if let Some(command) = parse_request() {
|
||||
self.client.send_command(command);
|
||||
self.response().write_str("OK")
|
||||
} else {
|
||||
self.response()
|
||||
}
|
||||
} else if req.match_str("z0,") {
|
||||
if let Some(address) = req.match_hex() {
|
||||
self.client
|
||||
.send_command(EmulatorCommand::RemoveBreakpoint(self.sim_id, address));
|
||||
} else if req.match_str("z") {
|
||||
let mut parse_request = || {
|
||||
let type_ = req.match_hex::<u8>()?;
|
||||
if !req.match_str(",") {
|
||||
return None;
|
||||
}
|
||||
let address = req.match_hex()?;
|
||||
if type_ == 0 || type_ == 1 {
|
||||
return Some(EmulatorCommand::RemoveBreakpoint(self.sim_id, address));
|
||||
}
|
||||
if !req.match_str(",") {
|
||||
return None;
|
||||
}
|
||||
let length = req.match_hex()?;
|
||||
let watch = match type_ {
|
||||
2 => VBWatchpointType::Write,
|
||||
3 => VBWatchpointType::Read,
|
||||
4 => VBWatchpointType::Access,
|
||||
_ => return None,
|
||||
};
|
||||
Some(EmulatorCommand::RemoveWatchpoint(
|
||||
self.sim_id,
|
||||
address,
|
||||
length,
|
||||
watch,
|
||||
))
|
||||
};
|
||||
if let Some(command) = parse_request() {
|
||||
self.client.send_command(command);
|
||||
self.response().write_str("OK")
|
||||
} else {
|
||||
self.response()
|
||||
@@ -367,11 +419,38 @@ impl Drop for GdbConnection {
|
||||
}
|
||||
}
|
||||
|
||||
fn debug_stop_reason_string(reason: Option<DebugStopReason>) -> &'static str {
|
||||
match reason {
|
||||
Some(DebugStopReason::Trace) => "T05;thread:p1.t1;threads:p1.t1;reason:trace;",
|
||||
Some(DebugStopReason::Breakpoint) => "T05;thread:p1.t1;threads:p1.t1;reason:breakpoint;",
|
||||
Some(DebugStopReason::Trapped) => "T05;swbreak;thread:p1.t1;threads:p1.t1;reason:trap;",
|
||||
None => "T00;thread:p1.t1;threads:p1.t1;",
|
||||
fn debug_stop_reason_string(reason: Option<DebugStopReason>) -> String {
|
||||
let mut result = String::new();
|
||||
result += if reason.is_some() { "T05;" } else { "T00;" };
|
||||
if let Some(DebugStopReason::Breakpoint) = reason {
|
||||
result += "swbreak;";
|
||||
}
|
||||
if let Some(DebugStopReason::Watchpoint(watch, address)) = reason {
|
||||
result += match watch {
|
||||
VBWatchpointType::Write => "watch:",
|
||||
VBWatchpointType::Read => "rwatch:",
|
||||
VBWatchpointType::Access => "awatch:",
|
||||
};
|
||||
result += &format!("{address:08x};");
|
||||
}
|
||||
|
||||
result += "thread:p1.t1;threads:p1.t1;";
|
||||
|
||||
if let Some(reason) = reason {
|
||||
result += "reason:";
|
||||
result += match reason {
|
||||
DebugStopReason::Trace => "trace;",
|
||||
DebugStopReason::Breakpoint => "breakpoint;",
|
||||
DebugStopReason::Watchpoint(_, _) => "watchpoint;",
|
||||
DebugStopReason::Trapped => "trap;",
|
||||
};
|
||||
}
|
||||
|
||||
if let Some(DebugStopReason::Watchpoint(_, address)) = reason {
|
||||
result += "description:";
|
||||
result += &hex::encode(address.to_string());
|
||||
result += ";";
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user