Skip to content

Commit 85a6acc

Browse files
committed
Store files in Vec
1 parent 72b9ce2 commit 85a6acc

File tree

6 files changed

+102
-98
lines changed

6 files changed

+102
-98
lines changed

examples/armv4t/emu.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use crate::mem_sniffer::{AccessKind, MemSniffer};
44
use crate::DynResult;
55

66
const HLE_RETURN_ADDR: u32 = 0x12345678;
7-
pub const FD_MAX: u32 = 256;
87

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

2726
pub(crate) watchpoints: Vec<u32>,
2827
pub(crate) breakpoints: Vec<u32>,
29-
pub(crate) files: [Option<std::fs::File>; FD_MAX as usize],
28+
pub(crate) files: Vec<Option<std::fs::File>>,
3029
}
3130

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

7674
watchpoints: Vec::new(),
7775
breakpoints: Vec::new(),
78-
files: [FILE_INIT; FD_MAX as usize],
76+
files: Vec::new(),
7977
})
8078
}
8179

examples/armv4t/gdb/host_io.rs

+63-54
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
use gdbstub::target;
2-
use std::io::{Read, Seek, Write};
3-
4-
use crate::emu::{Emu, FD_MAX};
5-
62
use gdbstub::target::ext::host_io::{
73
FsKind, HostIoErrno, HostIoError, HostIoOpenFlags, HostIoOpenMode, HostIoOutput, HostIoResult,
84
HostIoStat, HostIoToken,
95
};
6+
use std::io::{Read, Seek, Write};
7+
8+
use crate::emu::Emu;
109

1110
impl target::ext::host_io::HostIo for Emu {
1211
#[inline(always)]
@@ -29,6 +28,11 @@ impl target::ext::host_io::HostIo for Emu {
2928
Some(self)
3029
}
3130

31+
#[inline(always)]
32+
fn enable_fstat(&mut self) -> Option<target::ext::host_io::HostIoFstatOps<Self>> {
33+
Some(self)
34+
}
35+
3236
#[inline(always)]
3337
fn enable_unlink(&mut self) -> Option<target::ext::host_io::HostIoUnlinkOps<Self>> {
3438
Some(self)
@@ -52,10 +56,12 @@ impl target::ext::host_io::HostIoOpen for Emu {
5256
flags: HostIoOpenFlags,
5357
_mode: HostIoOpenMode,
5458
) -> HostIoResult<u32, Self> {
55-
let path = match std::str::from_utf8(filename) {
56-
Ok(v) => v,
57-
Err(_) => return Err(HostIoError::Errno(HostIoErrno::ENOENT)),
58-
};
59+
if filename.starts_with(b"/proc") {
60+
return Err(HostIoError::Errno(HostIoErrno::ENOENT));
61+
}
62+
63+
let path =
64+
std::str::from_utf8(filename).map_err(|_| HostIoError::Errno(HostIoErrno::ENOENT))?;
5965

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

80-
let n = 0;
81-
for n in 0..FD_MAX {
82-
if self.files[n as usize].is_none() {
83-
break;
86+
let n = match self.files.iter_mut().enumerate().find(|(_, f)| f.is_none()) {
87+
Some((n, free_file)) => {
88+
*free_file = Some(file);
89+
n
8490
}
85-
}
86-
if n == FD_MAX {
87-
return Err(HostIoError::Errno(HostIoErrno::ENFILE));
88-
}
91+
None => {
92+
self.files.push(Some(file));
93+
self.files.len() - 1
94+
}
95+
};
8996

90-
self.files[n as usize] = Some(file);
91-
Ok(n)
97+
Ok(n as u32)
9298
}
9399
}
94100

95101
impl target::ext::host_io::HostIoClose for Emu {
96102
fn close(&mut self, fd: u32) -> HostIoResult<(), Self> {
97-
if fd < FD_MAX {
98-
self.files[fd as usize]
99-
.take()
100-
.ok_or(HostIoError::Errno(HostIoErrno::EBADF))?;
103+
let fd: usize = fd as usize;
104+
if fd < self.files.len() {
105+
if fd == self.files.len() - 1 {
106+
self.files.pop();
107+
while let Some(None) = self.files.last() {
108+
self.files.pop();
109+
}
110+
} else {
111+
self.files[fd]
112+
.take()
113+
.ok_or(HostIoError::Errno(HostIoErrno::EBADF))?;
114+
}
101115
Ok(())
102116
} else {
103117
Err(HostIoError::Errno(HostIoErrno::EBADF))
@@ -113,8 +127,9 @@ impl target::ext::host_io::HostIoPread for Emu {
113127
offset: u32,
114128
output: HostIoOutput<'a>,
115129
) -> HostIoResult<HostIoToken<'a>, Self> {
116-
if fd < FD_MAX {
117-
if let Some(ref mut file) = self.files[fd as usize] {
130+
let fd: usize = fd as usize;
131+
if fd < self.files.len() {
132+
if let Some(ref mut file) = self.files[fd] {
118133
let mut buffer = vec![0; count as usize];
119134
file.seek(std::io::SeekFrom::Start(offset as u64))?;
120135
let n = file.read(&mut buffer)?;
@@ -130,8 +145,9 @@ impl target::ext::host_io::HostIoPread for Emu {
130145

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

147163
impl target::ext::host_io::HostIoFstat for Emu {
148164
fn fstat(&mut self, fd: u32) -> HostIoResult<HostIoStat, Self> {
149-
if fd < FD_MAX {
150-
if let Some(ref mut file) = self.files[fd as usize] {
165+
let fd: usize = fd as usize;
166+
if fd < self.files.len() {
167+
if let Some(ref mut file) = self.files[fd] {
151168
let metadata = file.metadata()?;
152-
let atime = metadata
153-
.accessed()
154-
.map_err(|_| HostIoError::Errno(HostIoErrno::EACCES))?
155-
.duration_since(std::time::SystemTime::UNIX_EPOCH)
156-
.map_err(|_| HostIoError::Errno(HostIoErrno::EACCES))?
157-
.as_secs() as u32;
158-
let mtime = metadata
159-
.modified()
160-
.map_err(|_| HostIoError::Errno(HostIoErrno::EACCES))?
161-
.duration_since(std::time::SystemTime::UNIX_EPOCH)
162-
.map_err(|_| HostIoError::Errno(HostIoErrno::EACCES))?
163-
.as_secs() as u32;
164-
let ctime = metadata
165-
.created()
166-
.map_err(|_| HostIoError::Errno(HostIoErrno::EACCES))?
167-
.duration_since(std::time::SystemTime::UNIX_EPOCH)
168-
.map_err(|_| HostIoError::Errno(HostIoErrno::EACCES))?
169-
.as_secs() as u32;
169+
macro_rules! time_to_secs {
170+
($time:expr) => {
171+
$time
172+
.map_err(|_| HostIoError::Errno(HostIoErrno::EACCES))?
173+
.duration_since(std::time::SystemTime::UNIX_EPOCH)
174+
.map_err(|_| HostIoError::Errno(HostIoErrno::EACCES))?
175+
.as_secs() as u32
176+
};
177+
}
178+
let atime = time_to_secs!(metadata.accessed());
179+
let mtime = time_to_secs!(metadata.modified());
180+
let ctime = time_to_secs!(metadata.created());
170181
Ok(HostIoStat {
171182
st_dev: 0,
172183
st_ino: 0,
@@ -193,10 +204,8 @@ impl target::ext::host_io::HostIoFstat for Emu {
193204

194205
impl target::ext::host_io::HostIoUnlink for Emu {
195206
fn unlink(&mut self, filename: &[u8]) -> HostIoResult<(), Self> {
196-
let path = match std::str::from_utf8(filename) {
197-
Ok(v) => v,
198-
Err(_) => return Err(HostIoError::Errno(HostIoErrno::ENOENT)),
199-
};
207+
let path =
208+
std::str::from_utf8(filename).map_err(|_| HostIoError::Errno(HostIoErrno::ENOENT))?;
200209
std::fs::remove_file(path)?;
201210
Ok(())
202211
}
@@ -214,12 +223,12 @@ impl target::ext::host_io::HostIoReadlink for Emu {
214223
} else if filename == b"/proc/1/cwd" {
215224
// Support `info proc cwd` command
216225
return Ok(output.write(b"/"));
226+
} else if filename.starts_with(b"/proc") {
227+
return Err(HostIoError::Errno(HostIoErrno::ENOENT));
217228
}
218229

219-
let path = match std::str::from_utf8(filename) {
220-
Ok(v) => v,
221-
Err(_) => return Err(HostIoError::Errno(HostIoErrno::ENOENT)),
222-
};
230+
let path =
231+
std::str::from_utf8(filename).map_err(|_| HostIoError::Errno(HostIoErrno::ENOENT))?;
223232
Ok(output.write(
224233
std::fs::read_link(path)?
225234
.to_str()

src/gdbstub_impl/ext/host_io.rs

+15-14
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use super::prelude::*;
2-
use crate::arch::Arch;
32
use crate::protocol::commands::ext::HostIo;
3+
4+
use crate::arch::Arch;
45
use crate::target::ext::host_io::{HostIoError, HostIoOutput, HostIoStat};
56
use crate::GdbStubError;
67

@@ -99,19 +100,19 @@ impl<T: Target, C: Connection> GdbStubImpl<T, C> {
99100
res.write_str("F")?;
100101
res.write_num(size)?;
101102
res.write_str(";")?;
102-
res.write_binary(&stat.st_dev.to_le_bytes())?;
103-
res.write_binary(&stat.st_ino.to_le_bytes())?;
104-
res.write_binary(&(stat.st_mode.bits()).to_le_bytes())?;
105-
res.write_binary(&stat.st_nlink.to_le_bytes())?;
106-
res.write_binary(&stat.st_uid.to_le_bytes())?;
107-
res.write_binary(&stat.st_gid.to_le_bytes())?;
108-
res.write_binary(&stat.st_rdev.to_le_bytes())?;
109-
res.write_binary(&stat.st_size.to_le_bytes())?;
110-
res.write_binary(&stat.st_blksize.to_le_bytes())?;
111-
res.write_binary(&stat.st_blocks.to_le_bytes())?;
112-
res.write_binary(&stat.st_atime.to_le_bytes())?;
113-
res.write_binary(&stat.st_mtime.to_le_bytes())?;
114-
res.write_binary(&stat.st_ctime.to_le_bytes())?;
103+
res.write_binary(&stat.st_dev.to_be_bytes())?;
104+
res.write_binary(&stat.st_ino.to_be_bytes())?;
105+
res.write_binary(&(stat.st_mode.bits()).to_be_bytes())?;
106+
res.write_binary(&stat.st_nlink.to_be_bytes())?;
107+
res.write_binary(&stat.st_uid.to_be_bytes())?;
108+
res.write_binary(&stat.st_gid.to_be_bytes())?;
109+
res.write_binary(&stat.st_rdev.to_be_bytes())?;
110+
res.write_binary(&stat.st_size.to_be_bytes())?;
111+
res.write_binary(&stat.st_blksize.to_be_bytes())?;
112+
res.write_binary(&stat.st_blocks.to_be_bytes())?;
113+
res.write_binary(&stat.st_atime.to_be_bytes())?;
114+
res.write_binary(&stat.st_mtime.to_be_bytes())?;
115+
res.write_binary(&stat.st_ctime.to_be_bytes())?;
115116
}
116117
};
117118
HandlerStatus::Handled

src/protocol/commands/_vFile_fstat.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@ impl<'a> ParseCommand<'a> for vFileFstat {
1414

1515
match body {
1616
[b':', body @ ..] => {
17-
let mut body = body.splitn_mut_no_panic(3, |b| *b == b',');
18-
let fd = decode_hex(body.next()?).ok()?;
17+
let fd = decode_hex(body).ok()?;
1918
Some(vFileFstat{fd})
2019
},
2120
_ => None,

src/protocol/commands/_vFile_setfs.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use super::prelude::*;
2+
23
use crate::target::ext::host_io::FsKind;
3-
use core::num::NonZeroUsize;
44

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

1717
match body {
1818
[b':', body @ ..] => {
19-
let fs = match NonZeroUsize::new(decode_hex(body).ok()?) {
19+
let fs = match core::num::NonZeroUsize::new(decode_hex(body).ok()?) {
2020
None => FsKind::Stub,
2121
Some(pid) => FsKind::Pid(pid),
2222
};

0 commit comments

Comments
 (0)