ckb_debugger/
syscall_file_stream.rs1use ckb_vm::{
2 Error, Memory, Register, SupportMachine, Syscalls,
3 registers::{A0, A1, A7},
4};
5
6#[derive(Clone)]
7pub struct FileStream {
8 content: Vec<u8>,
9 offset: usize,
10}
11
12impl Default for FileStream {
13 fn default() -> Self {
14 Self { content: Default::default(), offset: 0 }
15 }
16}
17
18impl FileStream {
19 pub fn new(file_name: &str) -> Self {
20 let content = crate::arch::file_read(file_name).unwrap();
21 FileStream { content, offset: 0 }
22 }
23
24 fn read(&mut self, buf: &mut [u8]) -> isize {
26 if self.offset >= self.content.len() {
27 return -1;
28 }
29 let remaining_size = self.content.len() - self.offset;
30 let read_size = std::cmp::min(buf.len(), remaining_size);
31 buf[0..read_size].copy_from_slice(&self.content[self.offset..self.offset + read_size]);
32
33 self.offset += read_size;
34 read_size as isize
35 }
36}
37
38impl<Mac: SupportMachine> Syscalls<Mac> for FileStream {
39 fn initialize(&mut self, _machine: &mut Mac) -> Result<(), Error> {
40 Ok(())
41 }
42
43 fn ecall(&mut self, machine: &mut Mac) -> Result<bool, Error> {
44 let id = machine.registers()[A7].to_u64();
45 if id != 9000 {
46 return Ok(false);
47 }
48 let arg_buf = machine.registers()[A0].to_u64();
49 let arg_count = machine.registers()[A1].to_u64();
50 let mut buf = vec![0u8; arg_count as usize];
51 let read_size = self.read(&mut buf);
52 if read_size > 0 {
53 machine.memory_mut().store_bytes(arg_buf, &buf[0..read_size as usize])?;
54 machine.set_register(A0, Mac::REG::from_u64(read_size as u64));
55 } else {
56 machine.set_register(A0, Mac::REG::from_i64(-1));
57 }
58 return Ok(true);
59 }
60}