Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,15 @@ pub type Tid = core::num::NonZeroUsize;

/// Process ID
pub type Pid = core::num::NonZeroUsize;

/// Endinanness.
///
/// This is used to report target endianness to the debugger as a
/// response to certain commands.
#[derive(Clone, Copy, Debug)]
pub enum Endianness {
/// Big-endian.
Big,
/// Little-endian.
Little,
}
8 changes: 8 additions & 0 deletions src/protocol/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,14 @@ commands! {
"qTsV" => _qTsV::qTsV,
}

host_info {
"qHostInfo" => _qHostInfo::qHostInfo,
}

process_info {
"qProcessInfo" => _qProcessInfo::qProcessInfo,
}

wasm use 'a {
"qWasmCallStack" => _qWasmCallStack::qWasmCallStack,
"qWasmLocal" => _qWasmLocal::qWasmLocal<'a>,
Expand Down
14 changes: 14 additions & 0 deletions src/protocol/commands/_qHostInfo.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use super::prelude::*;

#[derive(Debug)]
pub struct qHostInfo;

impl<'a> ParseCommand<'a> for qHostInfo {
#[inline(always)]
fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {
if !buf.into_body().is_empty() {
return None;
}
Some(qHostInfo)
}
}
14 changes: 14 additions & 0 deletions src/protocol/commands/_qProcessInfo.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use super::prelude::*;

#[derive(Debug)]
pub struct qProcessInfo;

impl<'a> ParseCommand<'a> for qProcessInfo {
#[inline(always)]
fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {
if !buf.into_body().is_empty() {
return None;
}
Some(qProcessInfo)
}
}
3 changes: 3 additions & 0 deletions src/stub/core_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ mod exec_file;
mod extended_mode;
mod flash;
mod host_io;
mod host_process_info;
mod libraries;
mod lldb_register_info;
mod memory_map;
Expand Down Expand Up @@ -224,6 +225,8 @@ impl<T: Target, C: Connection> GdbStubImpl<T, C> {
Command::LibrariesSvr4(cmd) => self.handle_libraries_svr4(res, target, cmd),
Command::Libraries(cmd) => self.handle_libraries(res, target, cmd),
Command::Tracepoints(cmd) => self.handle_tracepoints(res, target, cmd),
Command::HostInfo(cmd) => self.handle_host_info(res, target, cmd),
Command::ProcessInfo(cmd) => self.handle_process_info(res, target, cmd),
Command::Wasm(cmd) => self.handle_wasm(res, target, cmd),
// in the worst case, the command could not be parsed...
Command::Unknown(cmd) => {
Expand Down
134 changes: 134 additions & 0 deletions src/stub/core_impl/host_process_info.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
use super::prelude::*;
use crate::common::Endianness;
use crate::common::Pid;
use crate::protocol::commands::ext::HostInfo;
use crate::protocol::commands::ext::ProcessInfo;
use crate::protocol::ResponseWriterError;
use crate::target::ext::host_info::HostInfoResponse;
use crate::target::ext::process_info::ProcessInfoResponse;

pub(crate) enum InfoResponse<'a> {
Pid(Pid),
Triple(&'a str),
Endianness(Endianness),
PointerSize(usize),
}

impl<'a> InfoResponse<'a> {
pub(crate) fn write_response<C: Connection>(
&self,
res: &mut ResponseWriter<'_, C>,
) -> Result<(), ResponseWriterError<C::Error>> {
match self {
InfoResponse::Pid(pid) => {
res.write_str("pid:")?;
res.write_dec(usize::from(*pid))?;
}
InfoResponse::Triple(triple) => {
res.write_str("triple:")?;
res.write_hex_buf(triple.as_bytes())?;
}
InfoResponse::Endianness(endian) => {
res.write_str("endian:")?;
res.write_str(match endian {
Endianness::Big => "big;",
Endianness::Little => "little;",
})?;
}
InfoResponse::PointerSize(p) => {
res.write_str("ptrsize:")?;
res.write_dec(*p)?;
}
}
res.write_str(";")?;
Ok(())
}
}

impl<'a> From<&HostInfoResponse<'a>> for InfoResponse<'a> {
fn from(resp: &HostInfoResponse<'a>) -> Self {
match *resp {
HostInfoResponse::Triple(s) => InfoResponse::Triple(s),
HostInfoResponse::Endianness(e) => InfoResponse::Endianness(e),
HostInfoResponse::PointerSize(p) => InfoResponse::PointerSize(p),
}
}
}

impl<'a> From<&ProcessInfoResponse<'a>> for InfoResponse<'a> {
fn from(resp: &ProcessInfoResponse<'a>) -> Self {
match *resp {
ProcessInfoResponse::Pid(pid) => InfoResponse::Pid(pid),
ProcessInfoResponse::Triple(s) => InfoResponse::Triple(s),
ProcessInfoResponse::Endianness(e) => InfoResponse::Endianness(e),
ProcessInfoResponse::PointerSize(p) => InfoResponse::PointerSize(p),
}
}
}

impl<T: Target, C: Connection> GdbStubImpl<T, C> {
pub(crate) fn handle_process_info(
&mut self,
res: &mut ResponseWriter<'_, C>,
target: &mut T,
command: ProcessInfo,
) -> Result<HandlerStatus, Error<T::Error, C::Error>> {
let ops = match target.support_process_info() {
Some(ops) => ops,
None => return Ok(HandlerStatus::Handled),
};

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

let mut result = Ok(());
let mut write_info = |info: &ProcessInfoResponse<'_>| {
if result.is_ok() {
if let Err(e) = InfoResponse::from(info).write_response(res) {
result = Err(e);
}
}
};

match command {
ProcessInfo::qProcessInfo(_cmd) => {
ops.process_info(&mut write_info)
.map_err(Error::TargetError)?;
result?;
}
};

Ok(HandlerStatus::Handled)
}

pub(crate) fn handle_host_info(
&mut self,
res: &mut ResponseWriter<'_, C>,
target: &mut T,
command: HostInfo,
) -> Result<HandlerStatus, Error<T::Error, C::Error>> {
let ops = match target.support_host_info() {
Some(ops) => ops,
None => return Ok(HandlerStatus::Handled),
};

crate::__dead_code_marker!("host_info", "impl");

let mut result = Ok(());
let mut write_info = |info: &HostInfoResponse<'_>| {
if result.is_ok() {
if let Err(e) = InfoResponse::from(info).write_response(res) {
result = Err(e);
}
}
};

match command {
HostInfo::qHostInfo(_cmd) => {
ops.host_info(&mut write_info).map_err(Error::TargetError)?;
result?;
}
};

Ok(HandlerStatus::Handled)
}
}
45 changes: 45 additions & 0 deletions src/target/ext/host_info.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//! (LLDB extension) Provide host information to the debugger.
//!
//! This allows for reporting key-value metadata, for example the
//! target triple, endianness, and pointer size.
//!
//! This corresponds to the `qHostInfo` command in the LLDB
//! extensions.

use crate::common::Endianness;
use crate::target::Target;

/// A response key-value pair to a [HostInfo::host_info] query.
///
/// A response consists of a list of key-value pairs, each of which is
/// represented by one instance of this enum.
///
/// The allowed responses are documented in the [LLDB extension
/// documentation]. Not all supported responses are currently
/// represented in this enum. If you need another one, please feel
/// free to send a PR!
///
/// [LLDB extension documentation]: https://lldb.llvm.org/resources/lldbplatformpackets.html
#[derive(Clone, Copy)]
#[non_exhaustive]
pub enum HostInfoResponse<'a> {
/// The target triple for the debuggee, as a string.
Triple(&'a str),
/// The target endianness.
Endianness(Endianness),
/// The pointer size.
PointerSize(usize),
}

/// (LLDB extension) Target Extension - Provide host information.
pub trait HostInfo: Target {
/// Write a response to a host-info query.
///
/// Call `write_item` with each `HostInfoResponse` you wish to send.
fn host_info(
&self,
write_item: &mut dyn FnMut(&HostInfoResponse<'_>),
) -> Result<(), Self::Error>;
}

define_ext!(HostInfoOps, HostInfo);
2 changes: 2 additions & 0 deletions src/target/ext/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,11 +265,13 @@ pub mod catch_syscalls;
pub mod exec_file;
pub mod extended_mode;
pub mod flash;
pub mod host_info;
pub mod host_io;
pub mod libraries;
pub mod lldb_register_info_override;
pub mod memory_map;
pub mod monitor_cmd;
pub mod process_info;
pub mod section_offsets;
pub mod target_description_xml_override;
pub mod thread_extra_info;
Expand Down
49 changes: 49 additions & 0 deletions src/target/ext/process_info.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
//! (LLDB extension) Provide process information to the debugger.
//!
//! This allows for reporting key-value metadata, for example the
//! current PID, target triple, endianness, and pointer size.
//!
//! This corresponds to the `qHostInfo` command in the LLDB
//! extensions.

use crate::common::Endianness;
use crate::common::Pid;
use crate::target::Target;

/// A response key-value pair to a [ProcessInfo::process_info]
/// query.
///
/// A response consists of a list of key-value pairs, each of which is
/// represented by one instance of this enum.
///
/// The allowed responses are documented in the [LLDB extension
/// documentation]. Not all supported responses are currently
/// represented in this enum. If you need another one, please feel
/// free to send a PR!
///
/// [LLDB extension documentation]: https://lldb.llvm.org/resources/lldbplatformpackets.html
#[derive(Clone, Copy)]
#[non_exhaustive]
pub enum ProcessInfoResponse<'a> {
/// The current process PID.
Pid(Pid),
/// The target triple for the debuggee, as a string.
Triple(&'a str),
/// The target endianness.
Endianness(Endianness),
/// The pointer size.
PointerSize(usize),
}

/// (LLDB extension) Target Extension - Provide process information.
pub trait ProcessInfo: Target {
/// Write the response to process-info query.
///
/// Call `write_item` with each `InfoResponse` you wish to send.
fn process_info(
&self,
write_item: &mut dyn FnMut(&ProcessInfoResponse<'_>),
) -> Result<(), Self::Error>;
}

define_ext!(ProcessInfoOps, ProcessInfo);
12 changes: 12 additions & 0 deletions src/target/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -747,6 +747,18 @@ pub trait Target {
None
}

/// (LLDB extension) Support for reporting host information.
#[inline(always)]
fn support_host_info(&mut self) -> Option<ext::host_info::HostInfoOps<'_, Self>> {
None
}

/// (LLDB extension) Support for reporting process information.
#[inline(always)]
fn support_process_info(&mut self) -> Option<ext::process_info::ProcessInfoOps<'_, Self>> {
None
}

/// (LLDB extension) Support for WebAssembly (Wasm)-specific commands.
#[inline(always)]
fn support_wasm(&mut self) -> Option<ext::wasm::WasmOps<'_, Self>> {
Expand Down
Loading