aboutsummaryrefslogtreecommitdiff
path: root/src/stub/core_impl/host_io.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/stub/core_impl/host_io.rs')
-rw-r--r--src/stub/core_impl/host_io.rs140
1 files changed, 140 insertions, 0 deletions
diff --git a/src/stub/core_impl/host_io.rs b/src/stub/core_impl/host_io.rs
new file mode 100644
index 0000000..4ea6b1a
--- /dev/null
+++ b/src/stub/core_impl/host_io.rs
@@ -0,0 +1,140 @@
+use super::prelude::*;
+use crate::protocol::commands::ext::HostIo;
+
+use crate::arch::Arch;
+use crate::target::ext::host_io::{HostIoError, HostIoStat};
+
+impl<T: Target, C: Connection> GdbStubImpl<T, C> {
+ pub(crate) fn handle_host_io(
+ &mut self,
+ res: &mut ResponseWriter<'_, C>,
+ target: &mut T,
+ command: HostIo<'_>,
+ ) -> Result<HandlerStatus, Error<T::Error, C::Error>> {
+ let ops = match target.support_host_io() {
+ Some(ops) => ops,
+ None => return Ok(HandlerStatus::Handled),
+ };
+
+ crate::__dead_code_marker!("host_io", "impl");
+
+ macro_rules! handle_hostio_result {
+ ( if let Ok($val:pat) = $ret:expr => $callback:block ) => {{
+ match $ret {
+ Ok($val) => $callback,
+ Err(HostIoError::Errno(errno)) => {
+ res.write_str("F-1,")?;
+ res.write_num(errno as u32)?;
+ }
+ Err(HostIoError::Fatal(e)) => return Err(Error::TargetError(e)),
+ }
+ }};
+ }
+
+ let handler_status = match command {
+ HostIo::vFileOpen(cmd) if ops.support_open().is_some() => {
+ let ops = ops.support_open().unwrap();
+ handle_hostio_result! {
+ if let Ok(fd) = ops.open(cmd.filename, cmd.flags, cmd.mode) => {
+ res.write_str("F")?;
+ res.write_num(fd)?;
+ }
+ }
+ HandlerStatus::Handled
+ }
+ HostIo::vFileClose(cmd) if ops.support_close().is_some() => {
+ let ops = ops.support_close().unwrap();
+ handle_hostio_result! {
+ if let Ok(()) = ops.close(cmd.fd) => {
+ res.write_str("F0")?;
+ }
+ }
+ HandlerStatus::Handled
+ }
+ HostIo::vFilePread(cmd) if ops.support_pread().is_some() => {
+ let ops = ops.support_pread().unwrap();
+ handle_hostio_result! {
+ if let Ok(ret) = ops.pread(cmd.fd, cmd.count, cmd.offset, cmd.buf) => {
+ res.write_str("F")?;
+ res.write_num(ret)?;
+ res.write_str(";")?;
+ res.write_binary(cmd.buf.get(..ret).ok_or(Error::PacketBufferOverflow)?)?;
+ }
+ };
+
+ HandlerStatus::Handled
+ }
+ HostIo::vFilePwrite(cmd) if ops.support_pwrite().is_some() => {
+ let offset = <T::Arch as Arch>::Usize::from_be_bytes(cmd.offset)
+ .ok_or(Error::TargetMismatch)?;
+ let ops = ops.support_pwrite().unwrap();
+ handle_hostio_result! {
+ if let Ok(ret) = ops.pwrite(cmd.fd, offset, cmd.data) => {
+ res.write_str("F")?;
+ res.write_num(ret)?;
+ }
+ };
+ HandlerStatus::Handled
+ }
+ HostIo::vFileFstat(cmd) if ops.support_fstat().is_some() => {
+ let ops = ops.support_fstat().unwrap();
+ handle_hostio_result! {
+ if let Ok(stat) = ops.fstat(cmd.fd) => {
+ let size = core::mem::size_of::<HostIoStat>();
+ res.write_str("F")?;
+ res.write_num(size)?;
+ res.write_str(";")?;
+ res.write_binary(&stat.st_dev.to_be_bytes())?;
+ res.write_binary(&stat.st_ino.to_be_bytes())?;
+ res.write_binary(&(stat.st_mode.bits()).to_be_bytes())?;
+ res.write_binary(&stat.st_nlink.to_be_bytes())?;
+ res.write_binary(&stat.st_uid.to_be_bytes())?;
+ res.write_binary(&stat.st_gid.to_be_bytes())?;
+ res.write_binary(&stat.st_rdev.to_be_bytes())?;
+ res.write_binary(&stat.st_size.to_be_bytes())?;
+ res.write_binary(&stat.st_blksize.to_be_bytes())?;
+ res.write_binary(&stat.st_blocks.to_be_bytes())?;
+ res.write_binary(&stat.st_atime.to_be_bytes())?;
+ res.write_binary(&stat.st_mtime.to_be_bytes())?;
+ res.write_binary(&stat.st_ctime.to_be_bytes())?;
+ }
+ };
+ HandlerStatus::Handled
+ }
+ HostIo::vFileUnlink(cmd) if ops.support_unlink().is_some() => {
+ let ops = ops.support_unlink().unwrap();
+ handle_hostio_result! {
+ if let Ok(()) = ops.unlink(cmd.filename) => {
+ res.write_str("F0")?;
+ }
+ };
+ HandlerStatus::Handled
+ }
+ HostIo::vFileReadlink(cmd) if ops.support_readlink().is_some() => {
+ let ops = ops.support_readlink().unwrap();
+ handle_hostio_result! {
+ if let Ok(ret) = ops.readlink(cmd.filename, cmd.buf) => {
+ res.write_str("F")?;
+ res.write_num(ret)?;
+ res.write_str(";")?;
+ res.write_binary(cmd.buf.get(..ret).ok_or(Error::PacketBufferOverflow)?)?;
+ }
+ };
+
+ HandlerStatus::Handled
+ }
+ HostIo::vFileSetfs(cmd) if ops.support_setfs().is_some() => {
+ let ops = ops.support_setfs().unwrap();
+ handle_hostio_result! {
+ if let Ok(()) = ops.setfs(cmd.fs) => {
+ res.write_str("F0")?;
+ }
+ };
+ HandlerStatus::Handled
+ }
+ _ => HandlerStatus::Handled,
+ };
+
+ Ok(handler_status)
+ }
+}