From c8cc46f8e9ee868b61f19f43cbb8e33d9acb8c20 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 14 Dec 2023 13:03:34 -0800 Subject: [PATCH 1/8] Add support for `qXfer:libraries{,-svr4}:read` A toy project I've been working on involves loading a custom kernel and a custom guest into a KVM instance, and these commands enable `gdb` to be able to debug both the guest and the kernel at the same time by reporting where both images are loaded in the address space. Initially this commit only implemented `qXfer:libraries:read` but it turned out that gdb never actually used that command. When implementing `qXfer:libraries-svr4:read`, however, gdb invoked that automatically (presumably it's target-specific). I ended up including both here for completeness. --- src/protocol/commands.rs | 8 +++ .../commands/_qXfer_libraries_read.rs | 18 +++++ .../commands/_qXfer_libraries_svr4_read.rs | 18 +++++ src/stub/core_impl.rs | 3 + src/stub/core_impl/base.rs | 8 +++ src/stub/core_impl/libraries.rs | 68 +++++++++++++++++++ src/target/ext/libraries.rs | 50 ++++++++++++++ src/target/ext/mod.rs | 1 + src/target/mod.rs | 13 ++++ 9 files changed, 187 insertions(+) create mode 100644 src/protocol/commands/_qXfer_libraries_read.rs create mode 100644 src/protocol/commands/_qXfer_libraries_svr4_read.rs create mode 100644 src/stub/core_impl/libraries.rs create mode 100644 src/target/ext/libraries.rs diff --git a/src/protocol/commands.rs b/src/protocol/commands.rs index 1229899..5185b0c 100644 --- a/src/protocol/commands.rs +++ b/src/protocol/commands.rs @@ -330,4 +330,12 @@ commands! { lldb_register_info { "qRegisterInfo" => _qRegisterInfo::qRegisterInfo, } + + libraries use 'a { + "qXfer:libraries:read" => _qXfer_libraries_read::qXferLibrariesRead<'a>, + } + + libraries_svr4 use 'a { + "qXfer:libraries-svr4:read" => _qXfer_libraries_svr4_read::qXferLibrariesSvr4Read<'a>, + } } diff --git a/src/protocol/commands/_qXfer_libraries_read.rs b/src/protocol/commands/_qXfer_libraries_read.rs new file mode 100644 index 0000000..99cfae0 --- /dev/null +++ b/src/protocol/commands/_qXfer_libraries_read.rs @@ -0,0 +1,18 @@ +use crate::protocol::common::qxfer::ParseAnnex; +use crate::protocol::common::qxfer::QXferReadBase; + +pub type qXferLibrariesRead<'a> = QXferReadBase<'a, LibrariesAnnex>; + +#[derive(Debug)] +pub struct LibrariesAnnex; + +impl<'a> ParseAnnex<'a> for LibrariesAnnex { + #[inline(always)] + fn from_buf(buf: &[u8]) -> Option { + if buf != b"" { + return None; + } + + Some(LibrariesAnnex) + } +} diff --git a/src/protocol/commands/_qXfer_libraries_svr4_read.rs b/src/protocol/commands/_qXfer_libraries_svr4_read.rs new file mode 100644 index 0000000..be050f4 --- /dev/null +++ b/src/protocol/commands/_qXfer_libraries_svr4_read.rs @@ -0,0 +1,18 @@ +use crate::protocol::common::qxfer::ParseAnnex; +use crate::protocol::common::qxfer::QXferReadBase; + +pub type qXferLibrariesSvr4Read<'a> = QXferReadBase<'a, LibrariesSvr4Annex>; + +#[derive(Debug)] +pub struct LibrariesSvr4Annex; + +impl<'a> ParseAnnex<'a> for LibrariesSvr4Annex { + #[inline(always)] + fn from_buf(buf: &[u8]) -> Option { + if buf != b"" { + return None; + } + + Some(LibrariesSvr4Annex) + } +} diff --git a/src/stub/core_impl.rs b/src/stub/core_impl.rs index 07774d4..ebb6f54 100644 --- a/src/stub/core_impl.rs +++ b/src/stub/core_impl.rs @@ -31,6 +31,7 @@ mod catch_syscalls; mod exec_file; mod extended_mode; mod host_io; +mod libraries; mod lldb_register_info; mod memory_map; mod monitor_cmd; @@ -216,6 +217,8 @@ impl GdbStubImpl { Command::Auxv(cmd) => self.handle_auxv(res, target, cmd), Command::ThreadExtraInfo(cmd) => self.handle_thread_extra_info(res, target, cmd), Command::LldbRegisterInfo(cmd) => self.handle_lldb_register_info(res, target, cmd), + Command::Libraries(cmd) => self.handle_libraries(res, target, cmd), + Command::LibrariesSvr4(cmd) => self.handle_libraries_svr4(res, target, cmd), // in the worst case, the command could not be parsed... Command::Unknown(cmd) => { // HACK: if the user accidentally sends a resume command to a diff --git a/src/stub/core_impl/base.rs b/src/stub/core_impl/base.rs index 9110297..5a069cf 100644 --- a/src/stub/core_impl/base.rs +++ b/src/stub/core_impl/base.rs @@ -195,6 +195,14 @@ impl GdbStubImpl { res.write_str(";qXfer:auxv:read+")?; } + if target.support_libraries().is_some() { + res.write_str(";qXfer:libraries:read+")?; + } + + if target.support_libraries_svr4().is_some() { + res.write_str(";qXfer:libraries-svr4:read+")?; + } + HandlerStatus::Handled } diff --git a/src/stub/core_impl/libraries.rs b/src/stub/core_impl/libraries.rs new file mode 100644 index 0000000..fefc773 --- /dev/null +++ b/src/stub/core_impl/libraries.rs @@ -0,0 +1,68 @@ +use super::prelude::*; +use crate::protocol::commands::ext::{Libraries, LibrariesSvr4}; + +impl GdbStubImpl { + pub(crate) fn handle_libraries( + &mut self, + res: &mut ResponseWriter<'_, C>, + target: &mut T, + command: Libraries<'_>, + ) -> Result> { + let ops = match target.support_libraries() { + Some(ops) => ops, + None => return Ok(HandlerStatus::Handled), + }; + + crate::__dead_code_marker!("libraries", "impl"); + + let handler_status = match command { + Libraries::qXferLibrariesRead(cmd) => { + let ret = ops + .get_libraries(cmd.offset, cmd.length, cmd.buf) + .handle_error()?; + if ret == 0 { + res.write_str("l")?; + } else { + res.write_str("m")?; + // TODO: add more specific error variant? + res.write_binary(cmd.buf.get(..ret).ok_or(Error::PacketBufferOverflow)?)?; + } + HandlerStatus::Handled + } + }; + + Ok(handler_status) + } + + pub(crate) fn handle_libraries_svr4( + &mut self, + res: &mut ResponseWriter<'_, C>, + target: &mut T, + command: LibrariesSvr4<'_>, + ) -> Result> { + let ops = match target.support_libraries_svr4() { + Some(ops) => ops, + None => return Ok(HandlerStatus::Handled), + }; + + crate::__dead_code_marker!("libraries", "impl"); + + let handler_status = match command { + LibrariesSvr4::qXferLibrariesSvr4Read(cmd) => { + let ret = ops + .get_libraries_svr4(cmd.offset, cmd.length, cmd.buf) + .handle_error()?; + if ret == 0 { + res.write_str("l")?; + } else { + res.write_str("m")?; + // TODO: add more specific error variant? + res.write_binary(cmd.buf.get(..ret).ok_or(Error::PacketBufferOverflow)?)?; + } + HandlerStatus::Handled + } + }; + + Ok(handler_status) + } +} diff --git a/src/target/ext/libraries.rs b/src/target/ext/libraries.rs new file mode 100644 index 0000000..30fe45c --- /dev/null +++ b/src/target/ext/libraries.rs @@ -0,0 +1,50 @@ +//! TODO + +use crate::target::Target; +use crate::target::TargetResult; + +/// Target Extension - List a target's libraries. +pub trait Libraries: Target { + /// Get library list XML for this target. + /// + /// See the [GDB Documentation] for a description of the format. + /// + /// [GDB Documentation]: https://sourceware.org/gdb/current/onlinedocs/gdb.html/Library-List-Format.html + /// + /// Return the number of bytes written into `buf` (which may be less than + /// `length`). + /// + /// If `offset` is greater than the length of the underlying data, return + /// `Ok(0)`. + fn get_libraries( + &self, + offset: u64, + length: usize, + buf: &mut [u8], + ) -> TargetResult; +} + +define_ext!(LibrariesOps, Libraries); + +/// Target Extension - List an SVR4 (System-V/Unix) target's libraries. +pub trait LibrariesSvr4: Target { + /// Get library list XML for this target. + /// + /// See the [GDB Documentation] for a description of the format. + /// + /// [GDB Documentation]: https://sourceware.org/gdb/current/onlinedocs/gdb.html/Library-List-Format-for-SVR4-Targets.html + /// + /// Return the number of bytes written into `buf` (which may be less than + /// `length`). + /// + /// If `offset` is greater than the length of the underlying data, return + /// `Ok(0)`. + fn get_libraries_svr4( + &self, + offset: u64, + length: usize, + buf: &mut [u8], + ) -> TargetResult; +} + +define_ext!(LibrariesSvr4Ops, LibrariesSvr4); diff --git a/src/target/ext/mod.rs b/src/target/ext/mod.rs index b7e2d8f..a6f3d95 100644 --- a/src/target/ext/mod.rs +++ b/src/target/ext/mod.rs @@ -265,6 +265,7 @@ pub mod catch_syscalls; pub mod exec_file; pub mod extended_mode; pub mod host_io; +pub mod libraries; pub mod lldb_register_info_override; pub mod memory_map; pub mod monitor_cmd; diff --git a/src/target/mod.rs b/src/target/mod.rs index 2b00d0b..f186ccb 100644 --- a/src/target/mod.rs +++ b/src/target/mod.rs @@ -676,6 +676,19 @@ pub trait Target { fn support_auxv(&mut self) -> Option> { None } + + /// Support for reading a list of libraries non-SVR4 platforms. + #[inline(always)] + fn support_libraries(&mut self) -> Option> { + None + } + + /// Support for reading a list of libraries for SVR4 (System-V/Unix) + /// platforms. + #[inline(always)] + fn support_libraries_svr4(&mut self) -> Option> { + None + } } macro_rules! __delegate { From 44420355ab053277321899baf44762c6c774b3cb Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 14 Dec 2023 13:50:05 -0800 Subject: [PATCH 2/8] Add a note to the README --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 4ce94e4..8d48585 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,7 @@ Of course, most use-cases will want to support additional debugging features as - Can be used to automatically read the remote executable on attach (using `ExecFile`) - Read auxiliary vector (`info auxv`) - Extra thread info (`info threads`) +- Extra library information (`info sharedlibraries`) _Note:_ GDB features are implemented on an as-needed basis by `gdbstub`'s contributors. If there's a missing GDB feature that you'd like `gdbstub` to implement, please file an issue and/or open a PR! From 648b39f92a86e56de545db042928fcc47eef3527 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 14 Dec 2023 13:52:23 -0800 Subject: [PATCH 3/8] rustfmt --- src/stub/core_impl/libraries.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/stub/core_impl/libraries.rs b/src/stub/core_impl/libraries.rs index fefc773..bed402c 100644 --- a/src/stub/core_impl/libraries.rs +++ b/src/stub/core_impl/libraries.rs @@ -1,5 +1,6 @@ use super::prelude::*; -use crate::protocol::commands::ext::{Libraries, LibrariesSvr4}; +use crate::protocol::commands::ext::Libraries; +use crate::protocol::commands::ext::LibrariesSvr4; impl GdbStubImpl { pub(crate) fn handle_libraries( From 5f1f35b0d1595643e8363e8913123dc34a9e81d3 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 19 Dec 2023 10:29:57 -0800 Subject: [PATCH 4/8] Add armv4t example --- examples/armv4t/gdb/libraries.rs | 51 ++++++++++++++++++++++++++++++++ examples/armv4t/gdb/mod.rs | 13 ++++++++ 2 files changed, 64 insertions(+) create mode 100644 examples/armv4t/gdb/libraries.rs diff --git a/examples/armv4t/gdb/libraries.rs b/examples/armv4t/gdb/libraries.rs new file mode 100644 index 0000000..000ce15 --- /dev/null +++ b/examples/armv4t/gdb/libraries.rs @@ -0,0 +1,51 @@ +use super::copy_range_to_buf; +use crate::emu::Emu; +use gdbstub::target; +use gdbstub::target::TargetResult; + +impl target::ext::libraries::Libraries for Emu { + fn get_libraries( + &self, + offset: u64, + length: usize, + buf: &mut [u8], + ) -> TargetResult { + if true { + panic!() + } + let xml = r#" + + + + + +"# + .trim() + .as_bytes(); + Ok(copy_range_to_buf(xml, offset, length, buf)) + } +} + +impl target::ext::libraries::LibrariesSvr4 for Emu { + fn get_libraries_svr4( + &self, + offset: u64, + length: usize, + buf: &mut [u8], + ) -> TargetResult { + // `l_ld` is the address of the `PT_DYNAMIC` ELF segment, so fake an + // address here. + // + // The `main-lm`, `lm`, and `lmid` seem to refer to in-memory structures + // which gdb may read, but gdb also seems to work well enough if they're + // null-ish or otherwise pointing to non-present things. + let xml = r#" + + + +"# + .trim() + .as_bytes(); + Ok(copy_range_to_buf(xml, offset, length, buf)) + } +} diff --git a/examples/armv4t/gdb/mod.rs b/examples/armv4t/gdb/mod.rs index 5837ddd..23a64a5 100644 --- a/examples/armv4t/gdb/mod.rs +++ b/examples/armv4t/gdb/mod.rs @@ -20,6 +20,7 @@ mod catch_syscalls; mod exec_file; mod extended_mode; mod host_io; +mod libraries; mod lldb_register_info_override; mod memory_map; mod monitor_cmd; @@ -153,6 +154,18 @@ impl Target for Emu { fn support_auxv(&mut self) -> Option> { Some(self) } + + #[inline(always)] + fn support_libraries(&mut self) -> Option> { + Some(self) + } + + #[inline(always)] + fn support_libraries_svr4( + &mut self, + ) -> Option> { + Some(self) + } } impl SingleThreadBase for Emu { From 9a29b11f2269574b03f530bb92c8295b1b5cfbd5 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 19 Dec 2023 10:32:06 -0800 Subject: [PATCH 5/8] Remove support for `libraries` command Unknown how to actually get gdb to use it yet. --- examples/armv4t/gdb/libraries.rs | 23 ------------ examples/armv4t/gdb/mod.rs | 5 --- src/protocol/commands.rs | 4 --- .../commands/_qXfer_libraries_read.rs | 18 ---------- src/stub/core_impl.rs | 1 - src/stub/core_impl/base.rs | 4 --- src/stub/core_impl/libraries.rs | 35 +------------------ src/target/ext/libraries.rs | 23 ------------ src/target/mod.rs | 6 ---- 9 files changed, 1 insertion(+), 118 deletions(-) delete mode 100644 src/protocol/commands/_qXfer_libraries_read.rs diff --git a/examples/armv4t/gdb/libraries.rs b/examples/armv4t/gdb/libraries.rs index 000ce15..0c64dd7 100644 --- a/examples/armv4t/gdb/libraries.rs +++ b/examples/armv4t/gdb/libraries.rs @@ -3,29 +3,6 @@ use crate::emu::Emu; use gdbstub::target; use gdbstub::target::TargetResult; -impl target::ext::libraries::Libraries for Emu { - fn get_libraries( - &self, - offset: u64, - length: usize, - buf: &mut [u8], - ) -> TargetResult { - if true { - panic!() - } - let xml = r#" - - - - - -"# - .trim() - .as_bytes(); - Ok(copy_range_to_buf(xml, offset, length, buf)) - } -} - impl target::ext::libraries::LibrariesSvr4 for Emu { fn get_libraries_svr4( &self, diff --git a/examples/armv4t/gdb/mod.rs b/examples/armv4t/gdb/mod.rs index 23a64a5..b56ce9a 100644 --- a/examples/armv4t/gdb/mod.rs +++ b/examples/armv4t/gdb/mod.rs @@ -155,11 +155,6 @@ impl Target for Emu { Some(self) } - #[inline(always)] - fn support_libraries(&mut self) -> Option> { - Some(self) - } - #[inline(always)] fn support_libraries_svr4( &mut self, diff --git a/src/protocol/commands.rs b/src/protocol/commands.rs index 5185b0c..115e76b 100644 --- a/src/protocol/commands.rs +++ b/src/protocol/commands.rs @@ -331,10 +331,6 @@ commands! { "qRegisterInfo" => _qRegisterInfo::qRegisterInfo, } - libraries use 'a { - "qXfer:libraries:read" => _qXfer_libraries_read::qXferLibrariesRead<'a>, - } - libraries_svr4 use 'a { "qXfer:libraries-svr4:read" => _qXfer_libraries_svr4_read::qXferLibrariesSvr4Read<'a>, } diff --git a/src/protocol/commands/_qXfer_libraries_read.rs b/src/protocol/commands/_qXfer_libraries_read.rs deleted file mode 100644 index 99cfae0..0000000 --- a/src/protocol/commands/_qXfer_libraries_read.rs +++ /dev/null @@ -1,18 +0,0 @@ -use crate::protocol::common::qxfer::ParseAnnex; -use crate::protocol::common::qxfer::QXferReadBase; - -pub type qXferLibrariesRead<'a> = QXferReadBase<'a, LibrariesAnnex>; - -#[derive(Debug)] -pub struct LibrariesAnnex; - -impl<'a> ParseAnnex<'a> for LibrariesAnnex { - #[inline(always)] - fn from_buf(buf: &[u8]) -> Option { - if buf != b"" { - return None; - } - - Some(LibrariesAnnex) - } -} diff --git a/src/stub/core_impl.rs b/src/stub/core_impl.rs index ebb6f54..2ea3bc8 100644 --- a/src/stub/core_impl.rs +++ b/src/stub/core_impl.rs @@ -217,7 +217,6 @@ impl GdbStubImpl { Command::Auxv(cmd) => self.handle_auxv(res, target, cmd), Command::ThreadExtraInfo(cmd) => self.handle_thread_extra_info(res, target, cmd), Command::LldbRegisterInfo(cmd) => self.handle_lldb_register_info(res, target, cmd), - Command::Libraries(cmd) => self.handle_libraries(res, target, cmd), Command::LibrariesSvr4(cmd) => self.handle_libraries_svr4(res, target, cmd), // in the worst case, the command could not be parsed... Command::Unknown(cmd) => { diff --git a/src/stub/core_impl/base.rs b/src/stub/core_impl/base.rs index 5a069cf..eebb715 100644 --- a/src/stub/core_impl/base.rs +++ b/src/stub/core_impl/base.rs @@ -195,10 +195,6 @@ impl GdbStubImpl { res.write_str(";qXfer:auxv:read+")?; } - if target.support_libraries().is_some() { - res.write_str(";qXfer:libraries:read+")?; - } - if target.support_libraries_svr4().is_some() { res.write_str(";qXfer:libraries-svr4:read+")?; } diff --git a/src/stub/core_impl/libraries.rs b/src/stub/core_impl/libraries.rs index bed402c..dd18cb7 100644 --- a/src/stub/core_impl/libraries.rs +++ b/src/stub/core_impl/libraries.rs @@ -1,40 +1,7 @@ use super::prelude::*; -use crate::protocol::commands::ext::Libraries; use crate::protocol::commands::ext::LibrariesSvr4; impl GdbStubImpl { - pub(crate) fn handle_libraries( - &mut self, - res: &mut ResponseWriter<'_, C>, - target: &mut T, - command: Libraries<'_>, - ) -> Result> { - let ops = match target.support_libraries() { - Some(ops) => ops, - None => return Ok(HandlerStatus::Handled), - }; - - crate::__dead_code_marker!("libraries", "impl"); - - let handler_status = match command { - Libraries::qXferLibrariesRead(cmd) => { - let ret = ops - .get_libraries(cmd.offset, cmd.length, cmd.buf) - .handle_error()?; - if ret == 0 { - res.write_str("l")?; - } else { - res.write_str("m")?; - // TODO: add more specific error variant? - res.write_binary(cmd.buf.get(..ret).ok_or(Error::PacketBufferOverflow)?)?; - } - HandlerStatus::Handled - } - }; - - Ok(handler_status) - } - pub(crate) fn handle_libraries_svr4( &mut self, res: &mut ResponseWriter<'_, C>, @@ -46,7 +13,7 @@ impl GdbStubImpl { None => return Ok(HandlerStatus::Handled), }; - crate::__dead_code_marker!("libraries", "impl"); + crate::__dead_code_marker!("libraries-svr4", "impl"); let handler_status = match command { LibrariesSvr4::qXferLibrariesSvr4Read(cmd) => { diff --git a/src/target/ext/libraries.rs b/src/target/ext/libraries.rs index 30fe45c..16516f8 100644 --- a/src/target/ext/libraries.rs +++ b/src/target/ext/libraries.rs @@ -3,29 +3,6 @@ use crate::target::Target; use crate::target::TargetResult; -/// Target Extension - List a target's libraries. -pub trait Libraries: Target { - /// Get library list XML for this target. - /// - /// See the [GDB Documentation] for a description of the format. - /// - /// [GDB Documentation]: https://sourceware.org/gdb/current/onlinedocs/gdb.html/Library-List-Format.html - /// - /// Return the number of bytes written into `buf` (which may be less than - /// `length`). - /// - /// If `offset` is greater than the length of the underlying data, return - /// `Ok(0)`. - fn get_libraries( - &self, - offset: u64, - length: usize, - buf: &mut [u8], - ) -> TargetResult; -} - -define_ext!(LibrariesOps, Libraries); - /// Target Extension - List an SVR4 (System-V/Unix) target's libraries. pub trait LibrariesSvr4: Target { /// Get library list XML for this target. diff --git a/src/target/mod.rs b/src/target/mod.rs index f186ccb..da9541c 100644 --- a/src/target/mod.rs +++ b/src/target/mod.rs @@ -677,12 +677,6 @@ pub trait Target { None } - /// Support for reading a list of libraries non-SVR4 platforms. - #[inline(always)] - fn support_libraries(&mut self) -> Option> { - None - } - /// Support for reading a list of libraries for SVR4 (System-V/Unix) /// platforms. #[inline(always)] From 8d4f1d3e304961ce901952470bd857fa0216952c Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 2 Jan 2024 13:07:39 -0800 Subject: [PATCH 6/8] Fix a TODO --- src/target/ext/libraries.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/target/ext/libraries.rs b/src/target/ext/libraries.rs index 16516f8..5feea82 100644 --- a/src/target/ext/libraries.rs +++ b/src/target/ext/libraries.rs @@ -1,4 +1,6 @@ -//! TODO +//! Report information about the loaded shared libraries for targets where there +//! are possibly multiple files to be debugged mapped into the same address +//! space. use crate::target::Target; use crate::target::TargetResult; From 8d9998b3c86a12fc779996aa26ca0f7320beebd6 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 2 Jan 2024 13:10:41 -0800 Subject: [PATCH 7/8] Update `section_offsets` documentation --- src/target/ext/section_offsets.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/target/ext/section_offsets.rs b/src/target/ext/section_offsets.rs index eb80578..ec3d065 100644 --- a/src/target/ext/section_offsets.rs +++ b/src/target/ext/section_offsets.rs @@ -8,6 +8,12 @@ //! limited to reporting the offsets for code, data and bss, and is //! generally considered a legacy feature. //! +//! For System-V architectures GDB may use the `qXfer:libraries-svr4:read` +//! command to try to learn about loaded libraries and this can be implemented +//! with the [`LibrariesSvr4` trait](crate::target::ext::libraries::LibrariesSvr4). +//! Note that not all targets may query this and it may not be applicable in all +//! situations either. +//! //! For targets where library offsets are maintained externally (e.g. Windows) //! you should consider implementing the more flexible `qXfer:library:read`. //! See issue [#20](https://github.com/daniel5151/gdbstub/issues/20) for more From c7d0b0f912b5eeb6de3735ce0f6791bfecb7c882 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 4 Jan 2024 08:27:49 -0800 Subject: [PATCH 8/8] Run cargo fmt --- src/target/ext/section_offsets.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/target/ext/section_offsets.rs b/src/target/ext/section_offsets.rs index ec3d065..e778018 100644 --- a/src/target/ext/section_offsets.rs +++ b/src/target/ext/section_offsets.rs @@ -10,9 +10,10 @@ //! //! For System-V architectures GDB may use the `qXfer:libraries-svr4:read` //! command to try to learn about loaded libraries and this can be implemented -//! with the [`LibrariesSvr4` trait](crate::target::ext::libraries::LibrariesSvr4). -//! Note that not all targets may query this and it may not be applicable in all -//! situations either. +//! with the [`LibrariesSvr4` +//! trait](crate::target::ext::libraries::LibrariesSvr4). Note that not all +//! targets may query this and it may not be applicable in all situations +//! either. //! //! For targets where library offsets are maintained externally (e.g. Windows) //! you should consider implementing the more flexible `qXfer:library:read`.