Implement GDB/LLDB compatible server #3
|
@ -71,7 +71,6 @@ async fn run_server(
|
||||||
port: u16,
|
port: u16,
|
||||||
status: &Mutex<GdbServerStatus>,
|
status: &Mutex<GdbServerStatus>,
|
||||||
) {
|
) {
|
||||||
client.send_command(EmulatorCommand::Pause);
|
|
||||||
let Some(stream) = try_connect(port, status).await else {
|
let Some(stream) = try_connect(port, status).await else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
@ -142,43 +141,88 @@ impl GdbConnection {
|
||||||
}
|
}
|
||||||
async fn run(mut self) -> Result<()> {
|
async fn run(mut self) -> Result<()> {
|
||||||
println!("Connected for {}", self.sim_id);
|
println!("Connected for {}", self.sim_id);
|
||||||
self.client.send_command(EmulatorCommand::Resume);
|
self.client.send_command(EmulatorCommand::Pause);
|
||||||
loop {
|
loop {
|
||||||
let message = self.read_message().await?;
|
let message = self.read_message().await?;
|
||||||
println!("received {:?}", message);
|
println!("received {:?}", message);
|
||||||
|
|
||||||
let mut res = ResponseWriter::new(&mut self.stream_out);
|
//let mut res = ResponseWriter::new(&mut self.stream_out);
|
||||||
res.init(self.ack_messages).await?;
|
//res.init(self.ack_messages).await?;
|
||||||
|
|
||||||
let body = match &message {
|
let body = match &message {
|
||||||
Message::String(str) => str.as_str(),
|
Message::String(str) => str.as_str(),
|
||||||
Message::Signal => {
|
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?;
|
res.send().await?;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if body == "QStartNoAckMode" {
|
if body == "QStartNoAckMode" {
|
||||||
|
let mut res = ResponseWriter::new(&mut self.stream_out);
|
||||||
|
res.init(self.ack_messages).await?;
|
||||||
self.ack_messages = false;
|
self.ack_messages = false;
|
||||||
res.send_ok().await?;
|
res.send_ok().await?;
|
||||||
} else if body.starts_with("qSupported:") {
|
} else if body.starts_with("qSupported:") {
|
||||||
|
let mut res = self.respond().await?;
|
||||||
res.write_str("multiprocess+;swbreak+;vContSupported+")
|
res.write_str("multiprocess+;swbreak+;vContSupported+")
|
||||||
.await?;
|
.await?;
|
||||||
res.send().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?;
|
res.send_ok().await?;
|
||||||
} else if body == "qHostInfo" || body == "qProcessInfo" {
|
} else if body == "qHostInfo" {
|
||||||
|
let mut res = self.respond().await?;
|
||||||
res.write_str(&format!(
|
res.write_str(&format!(
|
||||||
"triple:{};endian:little;ptrsize:4;",
|
"triple:{};endian:little;ptrsize:4;",
|
||||||
hex::encode("v810-unknown-vb")
|
hex::encode("v810-unknown-vb")
|
||||||
))
|
))
|
||||||
.await?;
|
.await?;
|
||||||
res.send().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" {
|
} 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 {
|
} else {
|
||||||
// unrecognized command
|
// unrecognized command
|
||||||
|
let res = self.respond().await?;
|
||||||
res.send().await?;
|
res.send().await?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -235,6 +279,12 @@ impl GdbConnection {
|
||||||
async fn read_byte(&mut self) -> std::io::Result<u8> {
|
async fn read_byte(&mut self) -> std::io::Result<u8> {
|
||||||
self.stream_in.read_u8().await
|
self.stream_in.read_u8().await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn respond(&mut self) -> std::io::Result<ResponseWriter<'_>> {
|
||||||
|
let mut res = ResponseWriter::new(&mut self.stream_out);
|
||||||
|
res.init(self.ack_messages).await?;
|
||||||
|
Ok(res)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ResponseWriter<'a> {
|
struct ResponseWriter<'a> {
|
||||||
|
|
Loading…
Reference in New Issue