Skip to content

Commit

Permalink
Store files in Vec
Browse files Browse the repository at this point in the history
  • Loading branch information
bet4it committed Aug 16, 2021
1 parent 72b9ce2 commit 85a6acc
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 98 deletions.
6 changes: 2 additions & 4 deletions examples/armv4t/emu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use crate::mem_sniffer::{AccessKind, MemSniffer};
use crate::DynResult;

const HLE_RETURN_ADDR: u32 = 0x12345678;
pub const FD_MAX: u32 = 256;

#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum Event {
Expand All @@ -26,12 +25,11 @@ pub struct Emu {

pub(crate) watchpoints: Vec<u32>,
pub(crate) breakpoints: Vec<u32>,
pub(crate) files: [Option<std::fs::File>; FD_MAX as usize],
pub(crate) files: Vec<Option<std::fs::File>>,
}

impl Emu {
pub fn new(program_elf: &[u8]) -> DynResult<Emu> {
const FILE_INIT: Option<std::fs::File> = None;
// set up emulated system
let mut cpu = Cpu::new();
let mut mem = ExampleMem::new();
Expand Down Expand Up @@ -75,7 +73,7 @@ impl Emu {

watchpoints: Vec::new(),
breakpoints: Vec::new(),
files: [FILE_INIT; FD_MAX as usize],
files: Vec::new(),
})
}

Expand Down
117 changes: 63 additions & 54 deletions examples/armv4t/gdb/host_io.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
use gdbstub::target;
use std::io::{Read, Seek, Write};

use crate::emu::{Emu, FD_MAX};

use gdbstub::target::ext::host_io::{
FsKind, HostIoErrno, HostIoError, HostIoOpenFlags, HostIoOpenMode, HostIoOutput, HostIoResult,
HostIoStat, HostIoToken,
};
use std::io::{Read, Seek, Write};

use crate::emu::Emu;

impl target::ext::host_io::HostIo for Emu {
#[inline(always)]
Expand All @@ -29,6 +28,11 @@ impl target::ext::host_io::HostIo for Emu {
Some(self)
}

#[inline(always)]
fn enable_fstat(&mut self) -> Option<target::ext::host_io::HostIoFstatOps<Self>> {
Some(self)
}

#[inline(always)]
fn enable_unlink(&mut self) -> Option<target::ext::host_io::HostIoUnlinkOps<Self>> {
Some(self)
Expand All @@ -52,10 +56,12 @@ impl target::ext::host_io::HostIoOpen for Emu {
flags: HostIoOpenFlags,
_mode: HostIoOpenMode,
) -> HostIoResult<u32, Self> {
let path = match std::str::from_utf8(filename) {
Ok(v) => v,
Err(_) => return Err(HostIoError::Errno(HostIoErrno::ENOENT)),
};
if filename.starts_with(b"/proc") {
return Err(HostIoError::Errno(HostIoErrno::ENOENT));
}

let path =
std::str::from_utf8(filename).map_err(|_| HostIoError::Errno(HostIoErrno::ENOENT))?;

let mut read = false;
let mut write = false;
Expand All @@ -77,27 +83,35 @@ impl target::ext::host_io::HostIoOpen for Emu {
.create_new(flags.contains(HostIoOpenFlags::O_EXCL))
.open(path)?;

let n = 0;
for n in 0..FD_MAX {
if self.files[n as usize].is_none() {
break;
let n = match self.files.iter_mut().enumerate().find(|(_, f)| f.is_none()) {
Some((n, free_file)) => {
*free_file = Some(file);
n
}
}
if n == FD_MAX {
return Err(HostIoError::Errno(HostIoErrno::ENFILE));
}
None => {
self.files.push(Some(file));
self.files.len() - 1
}
};

self.files[n as usize] = Some(file);
Ok(n)
Ok(n as u32)
}
}

impl target::ext::host_io::HostIoClose for Emu {
fn close(&mut self, fd: u32) -> HostIoResult<(), Self> {
if fd < FD_MAX {
self.files[fd as usize]
.take()
.ok_or(HostIoError::Errno(HostIoErrno::EBADF))?;
let fd: usize = fd as usize;
if fd < self.files.len() {
if fd == self.files.len() - 1 {
self.files.pop();
while let Some(None) = self.files.last() {
self.files.pop();
}
} else {
self.files[fd]
.take()
.ok_or(HostIoError::Errno(HostIoErrno::EBADF))?;
}
Ok(())
} else {
Err(HostIoError::Errno(HostIoErrno::EBADF))
Expand All @@ -113,8 +127,9 @@ impl target::ext::host_io::HostIoPread for Emu {
offset: u32,
output: HostIoOutput<'a>,
) -> HostIoResult<HostIoToken<'a>, Self> {
if fd < FD_MAX {
if let Some(ref mut file) = self.files[fd as usize] {
let fd: usize = fd as usize;
if fd < self.files.len() {
if let Some(ref mut file) = self.files[fd] {
let mut buffer = vec![0; count as usize];
file.seek(std::io::SeekFrom::Start(offset as u64))?;
let n = file.read(&mut buffer)?;
Expand All @@ -130,8 +145,9 @@ impl target::ext::host_io::HostIoPread for Emu {

impl target::ext::host_io::HostIoPwrite for Emu {
fn pwrite(&mut self, fd: u32, offset: u32, data: &[u8]) -> HostIoResult<u32, Self> {
if fd < FD_MAX {
if let Some(ref mut file) = self.files[fd as usize] {
let fd: usize = fd as usize;
if fd < self.files.len() {
if let Some(ref mut file) = self.files[fd] {
file.seek(std::io::SeekFrom::Start(offset as u64))?;
let n = file.write(data)?;
Ok(n as u32)
Expand All @@ -146,27 +162,22 @@ impl target::ext::host_io::HostIoPwrite for Emu {

impl target::ext::host_io::HostIoFstat for Emu {
fn fstat(&mut self, fd: u32) -> HostIoResult<HostIoStat, Self> {
if fd < FD_MAX {
if let Some(ref mut file) = self.files[fd as usize] {
let fd: usize = fd as usize;
if fd < self.files.len() {
if let Some(ref mut file) = self.files[fd] {
let metadata = file.metadata()?;
let atime = metadata
.accessed()
.map_err(|_| HostIoError::Errno(HostIoErrno::EACCES))?
.duration_since(std::time::SystemTime::UNIX_EPOCH)
.map_err(|_| HostIoError::Errno(HostIoErrno::EACCES))?
.as_secs() as u32;
let mtime = metadata
.modified()
.map_err(|_| HostIoError::Errno(HostIoErrno::EACCES))?
.duration_since(std::time::SystemTime::UNIX_EPOCH)
.map_err(|_| HostIoError::Errno(HostIoErrno::EACCES))?
.as_secs() as u32;
let ctime = metadata
.created()
.map_err(|_| HostIoError::Errno(HostIoErrno::EACCES))?
.duration_since(std::time::SystemTime::UNIX_EPOCH)
.map_err(|_| HostIoError::Errno(HostIoErrno::EACCES))?
.as_secs() as u32;
macro_rules! time_to_secs {
($time:expr) => {
$time
.map_err(|_| HostIoError::Errno(HostIoErrno::EACCES))?
.duration_since(std::time::SystemTime::UNIX_EPOCH)
.map_err(|_| HostIoError::Errno(HostIoErrno::EACCES))?
.as_secs() as u32
};
}
let atime = time_to_secs!(metadata.accessed());
let mtime = time_to_secs!(metadata.modified());
let ctime = time_to_secs!(metadata.created());
Ok(HostIoStat {
st_dev: 0,
st_ino: 0,
Expand All @@ -193,10 +204,8 @@ impl target::ext::host_io::HostIoFstat for Emu {

impl target::ext::host_io::HostIoUnlink for Emu {
fn unlink(&mut self, filename: &[u8]) -> HostIoResult<(), Self> {
let path = match std::str::from_utf8(filename) {
Ok(v) => v,
Err(_) => return Err(HostIoError::Errno(HostIoErrno::ENOENT)),
};
let path =
std::str::from_utf8(filename).map_err(|_| HostIoError::Errno(HostIoErrno::ENOENT))?;
std::fs::remove_file(path)?;
Ok(())
}
Expand All @@ -214,12 +223,12 @@ impl target::ext::host_io::HostIoReadlink for Emu {
} else if filename == b"/proc/1/cwd" {
// Support `info proc cwd` command
return Ok(output.write(b"/"));
} else if filename.starts_with(b"/proc") {
return Err(HostIoError::Errno(HostIoErrno::ENOENT));
}

let path = match std::str::from_utf8(filename) {
Ok(v) => v,
Err(_) => return Err(HostIoError::Errno(HostIoErrno::ENOENT)),
};
let path =
std::str::from_utf8(filename).map_err(|_| HostIoError::Errno(HostIoErrno::ENOENT))?;
Ok(output.write(
std::fs::read_link(path)?
.to_str()
Expand Down
29 changes: 15 additions & 14 deletions src/gdbstub_impl/ext/host_io.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use super::prelude::*;
use crate::arch::Arch;
use crate::protocol::commands::ext::HostIo;

use crate::arch::Arch;
use crate::target::ext::host_io::{HostIoError, HostIoOutput, HostIoStat};
use crate::GdbStubError;

Expand Down Expand Up @@ -99,19 +100,19 @@ impl<T: Target, C: Connection> GdbStubImpl<T, C> {
res.write_str("F")?;
res.write_num(size)?;
res.write_str(";")?;
res.write_binary(&stat.st_dev.to_le_bytes())?;
res.write_binary(&stat.st_ino.to_le_bytes())?;
res.write_binary(&(stat.st_mode.bits()).to_le_bytes())?;
res.write_binary(&stat.st_nlink.to_le_bytes())?;
res.write_binary(&stat.st_uid.to_le_bytes())?;
res.write_binary(&stat.st_gid.to_le_bytes())?;
res.write_binary(&stat.st_rdev.to_le_bytes())?;
res.write_binary(&stat.st_size.to_le_bytes())?;
res.write_binary(&stat.st_blksize.to_le_bytes())?;
res.write_binary(&stat.st_blocks.to_le_bytes())?;
res.write_binary(&stat.st_atime.to_le_bytes())?;
res.write_binary(&stat.st_mtime.to_le_bytes())?;
res.write_binary(&stat.st_ctime.to_le_bytes())?;
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
Expand Down
3 changes: 1 addition & 2 deletions src/protocol/commands/_vFile_fstat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ impl<'a> ParseCommand<'a> for vFileFstat {

match body {
[b':', body @ ..] => {
let mut body = body.splitn_mut_no_panic(3, |b| *b == b',');
let fd = decode_hex(body.next()?).ok()?;
let fd = decode_hex(body).ok()?;
Some(vFileFstat{fd})
},
_ => None,
Expand Down
4 changes: 2 additions & 2 deletions src/protocol/commands/_vFile_setfs.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::prelude::*;

use crate::target::ext::host_io::FsKind;
use core::num::NonZeroUsize;

#[derive(Debug)]
pub struct vFileSetfs {
Expand All @@ -16,7 +16,7 @@ impl<'a> ParseCommand<'a> for vFileSetfs {

match body {
[b':', body @ ..] => {
let fs = match NonZeroUsize::new(decode_hex(body).ok()?) {
let fs = match core::num::NonZeroUsize::new(decode_hex(body).ok()?) {
None => FsKind::Stub,
Some(pid) => FsKind::Pid(pid),
};
Expand Down
Loading

0 comments on commit 85a6acc

Please sign in to comment.