Skip to content

Commit 3025cf7

Browse files
committed
Review feedback.
1 parent 6fb1b3d commit 3025cf7

3 files changed

Lines changed: 115 additions & 32 deletions

File tree

src/common/mod.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,15 @@ pub type Tid = core::num::NonZeroUsize;
99

1010
/// Process ID
1111
pub type Pid = core::num::NonZeroUsize;
12+
13+
/// Endinanness.
14+
///
15+
/// This is used to report target endianness to the debugger as a
16+
/// response to certain commands.
17+
#[derive(Clone, Copy, Debug)]
18+
pub enum Endianness {
19+
/// Big-endian.
20+
Big,
21+
/// Little-endian.
22+
Little,
23+
}

src/stub/core_impl/process_info.rs

Lines changed: 57 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,51 @@
11
use super::prelude::*;
2+
use crate::common::Endianness;
23
use crate::protocol::commands::ext::ProcessInfo;
4+
use crate::protocol::ResponseWriterError;
5+
use crate::target::ext::process_info::HostInfoResponse;
6+
use crate::target::ext::process_info::ProcessInfoResponse;
7+
8+
impl<'a> HostInfoResponse<'a> {
9+
fn write_response<C: Connection>(
10+
&self,
11+
res: &mut ResponseWriter<'_, C>,
12+
) -> Result<(), ResponseWriterError<C::Error>> {
13+
res.write_str("triple:")?;
14+
res.write_hex_buf(self.triple.as_bytes())?;
15+
res.write_str(";endian:")?;
16+
res.write_str(match self.endianness {
17+
Endianness::Big => "big",
18+
Endianness::Little => "little",
19+
})?;
20+
res.write_str(";ptrsize:")?;
21+
res.write_dec(self.ptrsize)?;
22+
res.write_str(";")?;
23+
Ok(())
24+
}
25+
}
26+
27+
impl<'a> ProcessInfoResponse<'a> {
28+
fn write_response<C: Connection>(
29+
&self,
30+
res: &mut ResponseWriter<'_, C>,
31+
) -> Result<(), ResponseWriterError<C::Error>> {
32+
res.write_str("pid:")?;
33+
res.write_dec(usize::from(self.pid))?;
34+
res.write_str(";")?;
35+
self.host_info_portion().write_response(res)?;
36+
Ok(())
37+
}
38+
39+
/// A ProcessInfoResponse is a superset of a HostInfoResponse; so
40+
/// we reuse the latter to emit most of our fields.
41+
fn host_info_portion(&self) -> HostInfoResponse<'a> {
42+
HostInfoResponse {
43+
triple: self.triple,
44+
endianness: self.endianness,
45+
ptrsize: self.ptrsize,
46+
}
47+
}
48+
}
349

450
impl<T: Target, C: Connection> GdbStubImpl<T, C> {
551
pub(crate) fn handle_process_info(
@@ -15,25 +61,22 @@ impl<T: Target, C: Connection> GdbStubImpl<T, C> {
1561

1662
crate::__dead_code_marker!("process_info", "impl");
1763

18-
let mut write_err = Ok(());
19-
let mut write_cb = |data: &[u8]| {
20-
if write_err.is_ok() {
21-
if let Err(e) = res.write_str(core::str::from_utf8(data).unwrap_or("")) {
22-
write_err = Err(e);
23-
}
24-
}
25-
};
26-
2764
let handler_status = match command {
2865
ProcessInfo::qHostInfo(_cmd) => {
29-
ops.host_info(&mut write_cb).map_err(Error::TargetError)?;
30-
write_err?;
66+
let mut result = Ok(());
67+
ops.host_info(&mut |info| {
68+
result = info.write_response(res);
69+
})
70+
.map_err(Error::TargetError)?;
71+
result?;
3172
HandlerStatus::Handled
3273
}
3374
ProcessInfo::qProcessInfo(_cmd) => {
34-
ops.process_info(&mut write_cb)
35-
.map_err(Error::TargetError)?;
36-
write_err?;
75+
let mut result = Ok(());
76+
ops.process_info(&mut |info| {
77+
result = info.write_response(res);
78+
})
79+
.map_err(Error::TargetError)?;
3780
HandlerStatus::Handled
3881
}
3982
};

src/target/ext/process_info.rs

Lines changed: 46 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,61 @@
22
//!
33
//! These correspond to the `qHostInfo` and `qProcessInfo` commands.
44
//! They report key-value metadata such as the target triple,
5-
//! endianness, pointer size, and process ID.
6-
//!
7-
//! The callback passed to these methods should be called with byte slices
8-
//! that together form a semicolon-delimited `key:value;` response string.
9-
//! For example:
10-
//!
11-
//! ```text
12-
//! triple:7761736d33322d756e6b6e6f776e2d756e6b6e6f776e2d7761736d;pid:1;endian:little;ptrsize:4;
13-
//! ```
14-
//!
15-
//! Note: the `triple` value must be hex-encoded.
5+
//! endianness, pointer size, and process ID. We take the information
6+
//! that we can return as responses to this commands in the
7+
//! [`HostInfoResponse`] and [`ProcessInfoResponse`] structs,
8+
//! respectively.
9+
10+
use crate::common::{Endianness, Pid};
11+
12+
/// A response to a `qProcessInfo` query from the debugger.
13+
///
14+
/// This does not contain all possible fields, but it contains a few
15+
/// common ones that are needed to satisfy some debuggers. More may be
16+
/// added in the future.
17+
pub struct ProcessInfoResponse<'a> {
18+
/// The PID.
19+
pub pid: Pid,
20+
/// The triple (e.g. `wasm32-wasi` or `x86_64-unknown-linux-gnu`).
21+
pub triple: &'a str,
22+
/// The target endianness.
23+
pub endianness: Endianness,
24+
/// The pointer size.
25+
pub ptrsize: usize,
26+
}
27+
28+
/// A response to a `qHostInfo` query from the debugger.
29+
///
30+
/// This does not contain all possible fields, but it contains a few
31+
/// common ones that are needed to satisfy some debuggers. More may be
32+
/// added in the future.
33+
pub struct HostInfoResponse<'a> {
34+
/// The triple (e.g. `wasm32-wasi` or `x86_64-unknown-linux-gnu`).
35+
pub triple: &'a str,
36+
/// The target endianness.
37+
pub endianness: Endianness,
38+
/// The pointer size.
39+
pub ptrsize: usize,
40+
}
1641

1742
use crate::target::Target;
1843

1944
/// Target Extension - Provide host and process information.
2045
pub trait ProcessInfo: Target {
21-
/// Write the response to `qHostInfo`.
46+
/// Write a response to `qHostInfo`.
2247
///
23-
/// Call `write` one or more times with byte slices that together form
24-
/// the response. Each call appends to the output.
25-
fn host_info(&self, write: &mut dyn FnMut(&[u8])) -> Result<(), Self::Error>;
48+
/// Call `respond` with a `HostInfoResponse` in order to send an
49+
/// appropriate response.
50+
fn host_info(&self, respond: &mut dyn FnMut(&HostInfoResponse<'_>)) -> Result<(), Self::Error>;
2651

2752
/// Write the response to `qProcessInfo`.
2853
///
29-
/// Call `write` one or more times with byte slices that together form
30-
/// the response. Each call appends to the output.
31-
fn process_info(&self, write: &mut dyn FnMut(&[u8])) -> Result<(), Self::Error>;
54+
/// Call `respond` with a `ProcessInfoResponse` in order to send an
55+
/// appropriate response.
56+
fn process_info(
57+
&self,
58+
respond: &mut dyn FnMut(&ProcessInfoResponse<'_>),
59+
) -> Result<(), Self::Error>;
3260
}
3361

3462
define_ext!(ProcessInfoOps, ProcessInfo);

0 commit comments

Comments
 (0)