1 use super::prelude::*; 2 use crate::arch::Arch; 3 use crate::protocol::commands::ext::HostIo; 4 use crate::target::ext::host_io::HostIoError; 5 use crate::target::ext::host_io::HostIoStat; 6 7 impl<T: Target, C: Connection> GdbStubImpl<T, C> { handle_host_io( &mut self, res: &mut ResponseWriter<'_, C>, target: &mut T, command: HostIo<'_>, ) -> Result<HandlerStatus, Error<T::Error, C::Error>>8 pub(crate) fn handle_host_io( 9 &mut self, 10 res: &mut ResponseWriter<'_, C>, 11 target: &mut T, 12 command: HostIo<'_>, 13 ) -> Result<HandlerStatus, Error<T::Error, C::Error>> { 14 let ops = match target.support_host_io() { 15 Some(ops) => ops, 16 None => return Ok(HandlerStatus::Handled), 17 }; 18 19 crate::__dead_code_marker!("host_io", "impl"); 20 21 macro_rules! handle_hostio_result { 22 ( if let Ok($val:pat) = $ret:expr => $callback:block ) => {{ 23 match $ret { 24 Ok($val) => $callback, 25 Err(HostIoError::Errno(errno)) => { 26 res.write_str("F-1,")?; 27 res.write_num(errno as u32)?; 28 } 29 Err(HostIoError::Fatal(e)) => return Err(Error::TargetError(e)), 30 } 31 }}; 32 } 33 34 let handler_status = match command { 35 HostIo::vFileOpen(cmd) if ops.support_open().is_some() => { 36 let ops = ops.support_open().unwrap(); 37 handle_hostio_result! { 38 if let Ok(fd) = ops.open(cmd.filename, cmd.flags, cmd.mode) => { 39 res.write_str("F")?; 40 res.write_num(fd)?; 41 } 42 } 43 HandlerStatus::Handled 44 } 45 HostIo::vFileClose(cmd) if ops.support_close().is_some() => { 46 let ops = ops.support_close().unwrap(); 47 handle_hostio_result! { 48 if let Ok(()) = ops.close(cmd.fd) => { 49 res.write_str("F0")?; 50 } 51 } 52 HandlerStatus::Handled 53 } 54 HostIo::vFilePread(cmd) if ops.support_pread().is_some() => { 55 let ops = ops.support_pread().unwrap(); 56 handle_hostio_result! { 57 if let Ok(ret) = ops.pread(cmd.fd, cmd.count, cmd.offset, cmd.buf) => { 58 res.write_str("F")?; 59 res.write_num(ret)?; 60 res.write_str(";")?; 61 res.write_binary(cmd.buf.get(..ret).ok_or(Error::PacketBufferOverflow)?)?; 62 } 63 }; 64 65 HandlerStatus::Handled 66 } 67 HostIo::vFilePwrite(cmd) if ops.support_pwrite().is_some() => { 68 let offset = <T::Arch as Arch>::Usize::from_be_bytes(cmd.offset) 69 .ok_or(Error::TargetMismatch)?; 70 let ops = ops.support_pwrite().unwrap(); 71 handle_hostio_result! { 72 if let Ok(ret) = ops.pwrite(cmd.fd, offset, cmd.data) => { 73 res.write_str("F")?; 74 res.write_num(ret)?; 75 } 76 }; 77 HandlerStatus::Handled 78 } 79 HostIo::vFileFstat(cmd) if ops.support_fstat().is_some() => { 80 let ops = ops.support_fstat().unwrap(); 81 handle_hostio_result! { 82 if let Ok(stat) = ops.fstat(cmd.fd) => { 83 let size = core::mem::size_of::<HostIoStat>(); 84 res.write_str("F")?; 85 res.write_num(size)?; 86 res.write_str(";")?; 87 res.write_binary(&stat.st_dev.to_be_bytes())?; 88 res.write_binary(&stat.st_ino.to_be_bytes())?; 89 res.write_binary(&(stat.st_mode.bits()).to_be_bytes())?; 90 res.write_binary(&stat.st_nlink.to_be_bytes())?; 91 res.write_binary(&stat.st_uid.to_be_bytes())?; 92 res.write_binary(&stat.st_gid.to_be_bytes())?; 93 res.write_binary(&stat.st_rdev.to_be_bytes())?; 94 res.write_binary(&stat.st_size.to_be_bytes())?; 95 res.write_binary(&stat.st_blksize.to_be_bytes())?; 96 res.write_binary(&stat.st_blocks.to_be_bytes())?; 97 res.write_binary(&stat.st_atime.to_be_bytes())?; 98 res.write_binary(&stat.st_mtime.to_be_bytes())?; 99 res.write_binary(&stat.st_ctime.to_be_bytes())?; 100 } 101 }; 102 HandlerStatus::Handled 103 } 104 HostIo::vFileUnlink(cmd) if ops.support_unlink().is_some() => { 105 let ops = ops.support_unlink().unwrap(); 106 handle_hostio_result! { 107 if let Ok(()) = ops.unlink(cmd.filename) => { 108 res.write_str("F0")?; 109 } 110 }; 111 HandlerStatus::Handled 112 } 113 HostIo::vFileReadlink(cmd) if ops.support_readlink().is_some() => { 114 let ops = ops.support_readlink().unwrap(); 115 handle_hostio_result! { 116 if let Ok(ret) = ops.readlink(cmd.filename, cmd.buf) => { 117 res.write_str("F")?; 118 res.write_num(ret)?; 119 res.write_str(";")?; 120 res.write_binary(cmd.buf.get(..ret).ok_or(Error::PacketBufferOverflow)?)?; 121 } 122 }; 123 124 HandlerStatus::Handled 125 } 126 HostIo::vFileSetfs(cmd) if ops.support_setfs().is_some() => { 127 let ops = ops.support_setfs().unwrap(); 128 handle_hostio_result! { 129 if let Ok(()) = ops.setfs(cmd.fs) => { 130 res.write_str("F0")?; 131 } 132 }; 133 HandlerStatus::Handled 134 } 135 _ => HandlerStatus::Handled, 136 }; 137 138 Ok(handler_status) 139 } 140 } 141