From 582ed561f065f76d1f24f23d94d8b47c3a1cf9bd Mon Sep 17 00:00:00 2001 From: Xuejie Xiao Date: Fri, 19 Jul 2024 06:20:29 +0000 Subject: [PATCH] Implement writev syscall in stdio musl actually uses writev instead of write syscall to print to stdout. Adding this new syscall implementation makes ckb-debugger nicer to musl. Note that musl actually issues ioctl before issuing writev syscall as well, however, ioctl is one messy component, it might be better that we keep it simple so the debugger only handles writev for now. We can hijack ioctl like we do now in musl. --- ckb-vm-debug-utils/src/stdio.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/ckb-vm-debug-utils/src/stdio.rs b/ckb-vm-debug-utils/src/stdio.rs index ee69f95..f00d8cc 100644 --- a/ckb-vm-debug-utils/src/stdio.rs +++ b/ckb-vm-debug-utils/src/stdio.rs @@ -147,6 +147,31 @@ impl Stdio { machine.set_register(A0, Mac::REG::from_u64(ret as u64)); Ok(()) } + + fn writev(&mut self, machine: &mut Mac) -> Result<(), Error> { + let fd = machine.registers()[A0].to_i32(); + let iov = machine.registers()[A1].to_u64(); + let iovcnt = machine.registers()[A2].to_u64(); + + let mut written = 0; + for i in 0..iovcnt { + let base = machine.memory_mut().load64(&Mac::REG::from_u64(iov + i * 16))?.to_u64(); + let len = machine.memory_mut().load64(&Mac::REG::from_u64(iov + i * 16 + 8))?.to_u64(); + + let buf = machine.memory_mut().load_bytes(base, len)?; + + written += match write(fd, &buf) { + Ok(w) => w as u64, + Err(e) => { + debug!("write error: {:?}", e); + machine.set_register(A0, Mac::REG::from_i64(-1)); + return Ok(()); + } + }; + } + machine.set_register(A0, Mac::REG::from_u64(written)); + Ok(()) + } } impl Syscalls for Stdio { @@ -160,6 +185,7 @@ impl Syscalls for Stdio { 62 => self.lseek(machine)?, 63 => self.read(machine)?, 64 => self.write(machine)?, + 66 => self.writev(machine)?, 80 => self.fstat(machine)?, _ => return Ok(false), };