From 24487b21b7df00bd35c24889b9e85dc4d90128aa Mon Sep 17 00:00:00 2001 From: Simon Gellis Date: Wed, 1 Jan 2025 14:56:54 -0500 Subject: [PATCH] Support pausing and resuming --- src/gdbserver.rs | 66 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 58 insertions(+), 8 deletions(-) diff --git a/src/gdbserver.rs b/src/gdbserver.rs index 2d90c11..4f0a78d 100644 --- a/src/gdbserver.rs +++ b/src/gdbserver.rs @@ -71,7 +71,6 @@ async fn run_server( port: u16, status: &Mutex, ) { - client.send_command(EmulatorCommand::Pause); let Some(stream) = try_connect(port, status).await else { return; }; @@ -142,43 +141,88 @@ impl GdbConnection { } async fn run(mut self) -> Result<()> { println!("Connected for {}", self.sim_id); - self.client.send_command(EmulatorCommand::Resume); + self.client.send_command(EmulatorCommand::Pause); loop { let message = self.read_message().await?; println!("received {:?}", message); - let mut res = ResponseWriter::new(&mut self.stream_out); - res.init(self.ack_messages).await?; + //let mut res = ResponseWriter::new(&mut self.stream_out); + //res.init(self.ack_messages).await?; let body = match &message { Message::String(str) => str.as_str(), Message::Signal => { - // TODO: handle this + self.client.send_command(EmulatorCommand::Pause); + let mut res = self.respond().await?; + res.write_str("T05;thread:p1.t1;threads:p1.t1;reason:trap;") + .await?; res.send().await?; continue; } }; if body == "QStartNoAckMode" { + let mut res = ResponseWriter::new(&mut self.stream_out); + res.init(self.ack_messages).await?; self.ack_messages = false; res.send_ok().await?; } else if body.starts_with("qSupported:") { + let mut res = self.respond().await?; res.write_str("multiprocess+;swbreak+;vContSupported+") .await?; res.send().await?; - } else if body == "QThreadSuffixSupported" || body == "QListThreadsInStopReply" { + } else if body == "QThreadSuffixSupported" + || body == "QListThreadsInStopReply" + || body == "QEnableErrorStrings" + { + let res = self.respond().await?; res.send_ok().await?; - } else if body == "qHostInfo" || body == "qProcessInfo" { + } else if body == "qHostInfo" { + let mut res = self.respond().await?; res.write_str(&format!( "triple:{};endian:little;ptrsize:4;", hex::encode("v810-unknown-vb") )) .await?; res.send().await?; + } else if body == "qProcessInfo" { + let mut res = self.respond().await?; + res.write_str(&format!( + "pid:1;triple:{};endian:little;ptrsize:4;", + hex::encode("v810-unknown-vb") + )) + .await?; + res.send().await?; + } else if body == "vCont?" { + let mut res = self.respond().await?; + res.write_str("vCont;c;").await?; + res.send().await?; + } else if body == "qC" { + // The v810 has no threads, so report that the "current thread" is 1. + let mut res = self.respond().await?; + res.write_str("QCp1.t1").await?; + res.send().await?; + } else if body == "qfThreadInfo" { + let mut res = self.respond().await?; + res.write_str("mp1.t1").await?; + res.send().await?; + } else if body == "qsThreadInfo" { + let mut res = self.respond().await?; + res.write_str("l").await?; + res.send().await?; } else if body == "k" { - return Ok(()); + bail!("debug process was killed"); + } else if body == "?" { + let mut res = self.respond().await?; + res.write_str("T00;thread:p1.t1;threads:p1.t1;").await?; + res.send().await?; + } else if body == "c" || body.starts_with("vCont;c:") { + // Continue running the game until we're interrupted again + self.client.send_command(EmulatorCommand::Resume); + continue; } else { // unrecognized command + let res = self.respond().await?; res.send().await?; } } @@ -235,6 +279,12 @@ impl GdbConnection { async fn read_byte(&mut self) -> std::io::Result { self.stream_in.read_u8().await } + + async fn respond(&mut self) -> std::io::Result> { + let mut res = ResponseWriter::new(&mut self.stream_out); + res.init(self.ack_messages).await?; + Ok(res) + } } struct ResponseWriter<'a> {