Skip to content

Commit a180665

Browse files
committed
Add support for qProcessInfo and qHostInfo queries.
These are necessary in some cases to allow LLDB to use appropriate target-specific behaviors or modules. For example, when debugging a Wasm target, LLDB requires the stub to declare that it has a wasm32 architecture in order to actually use its Wasm module loader over the wire.
1 parent 0525c9a commit a180665

8 files changed

Lines changed: 123 additions & 0 deletions

File tree

src/protocol/commands.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,4 +366,9 @@ commands! {
366366
"qTfV" => _qTfV::qTfV,
367367
"qTsV" => _qTsV::qTsV,
368368
}
369+
370+
process_info {
371+
"qHostInfo" => _qHostInfo::qHostInfo,
372+
"qProcessInfo" => _qProcessInfo::qProcessInfo,
373+
}
369374
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
use super::prelude::*;
2+
3+
#[derive(Debug)]
4+
pub struct qHostInfo;
5+
6+
impl<'a> ParseCommand<'a> for qHostInfo {
7+
#[inline(always)]
8+
fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {
9+
if !buf.into_body().is_empty() {
10+
return None;
11+
}
12+
Some(qHostInfo)
13+
}
14+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
use super::prelude::*;
2+
3+
#[derive(Debug)]
4+
pub struct qProcessInfo;
5+
6+
impl<'a> ParseCommand<'a> for qProcessInfo {
7+
#[inline(always)]
8+
fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {
9+
if !buf.into_body().is_empty() {
10+
return None;
11+
}
12+
Some(qProcessInfo)
13+
}
14+
}

src/stub/core_impl.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ mod lldb_register_info;
3737
mod memory_map;
3838
mod monitor_cmd;
3939
mod no_ack_mode;
40+
mod process_info;
4041
mod resume;
4142
mod reverse_exec;
4243
mod section_offsets;
@@ -223,6 +224,7 @@ impl<T: Target, C: Connection> GdbStubImpl<T, C> {
223224
Command::LibrariesSvr4(cmd) => self.handle_libraries_svr4(res, target, cmd),
224225
Command::Libraries(cmd) => self.handle_libraries(res, target, cmd),
225226
Command::Tracepoints(cmd) => self.handle_tracepoints(res, target, cmd),
227+
Command::ProcessInfo(cmd) => self.handle_process_info(res, target, cmd),
226228
// in the worst case, the command could not be parsed...
227229
Command::Unknown(cmd) => {
228230
// HACK: if the user accidentally sends a resume command to a

src/stub/core_impl/process_info.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
use super::prelude::*;
2+
use crate::protocol::commands::ext::ProcessInfo;
3+
4+
impl<T: Target, C: Connection> GdbStubImpl<T, C> {
5+
pub(crate) fn handle_process_info(
6+
&mut self,
7+
res: &mut ResponseWriter<'_, C>,
8+
target: &mut T,
9+
command: ProcessInfo,
10+
) -> Result<HandlerStatus, Error<T::Error, C::Error>> {
11+
let ops = match target.support_process_info() {
12+
Some(ops) => ops,
13+
None => return Ok(HandlerStatus::Handled),
14+
};
15+
16+
crate::__dead_code_marker!("process_info", "impl");
17+
18+
let mut write_err: Option<Error<T::Error, C::Error>> = None;
19+
let mut write_cb = |data: &[u8]| {
20+
if write_err.is_none() {
21+
if let Err(e) = res.write_str(core::str::from_utf8(data).unwrap_or("")) {
22+
write_err = Some(e.into());
23+
}
24+
}
25+
};
26+
27+
let handler_status = match command {
28+
ProcessInfo::qHostInfo(_cmd) => {
29+
ops.host_info(&mut write_cb).map_err(Error::TargetError)?;
30+
if let Some(e) = write_err {
31+
return Err(e);
32+
}
33+
HandlerStatus::Handled
34+
}
35+
ProcessInfo::qProcessInfo(_cmd) => {
36+
ops.process_info(&mut write_cb)
37+
.map_err(Error::TargetError)?;
38+
if let Some(e) = write_err {
39+
return Err(e);
40+
}
41+
HandlerStatus::Handled
42+
}
43+
};
44+
45+
Ok(handler_status)
46+
}
47+
}

src/target/ext/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,7 @@ pub mod libraries;
270270
pub mod lldb_register_info_override;
271271
pub mod memory_map;
272272
pub mod monitor_cmd;
273+
pub mod process_info;
273274
pub mod section_offsets;
274275
pub mod target_description_xml_override;
275276
pub mod thread_extra_info;

src/target/ext/process_info.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
//! Provide host and process information to the debugger.
2+
//!
3+
//! These correspond to the `qHostInfo` and `qProcessInfo` commands.
4+
//! 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.
16+
17+
use crate::target::Target;
18+
19+
/// Target Extension - Provide host and process information.
20+
pub trait ProcessInfo: Target {
21+
/// Write the response to `qHostInfo`.
22+
///
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>;
26+
27+
/// Write the response to `qProcessInfo`.
28+
///
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>;
32+
}
33+
34+
define_ext!(ProcessInfoOps, ProcessInfo);

src/target/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -746,6 +746,12 @@ pub trait Target {
746746
fn support_libraries(&mut self) -> Option<ext::libraries::LibrariesOps<'_, Self>> {
747747
None
748748
}
749+
750+
/// Support for host and process information (qHostInfo / qProcessInfo).
751+
#[inline(always)]
752+
fn support_process_info(&mut self) -> Option<ext::process_info::ProcessInfoOps<'_, Self>> {
753+
None
754+
}
749755
}
750756

751757
macro_rules! __delegate {

0 commit comments

Comments
 (0)