diff --git a/libcc2rs/src/rc.rs b/libcc2rs/src/rc.rs index 30bc5ef2..6f6941e5 100644 --- a/libcc2rs/src/rc.rs +++ b/libcc2rs/src/rc.rs @@ -950,6 +950,64 @@ thread_local! { } impl Ptr { + pub fn with_slice_mut(&self, len: usize, f: impl FnOnce(&mut [u8]) -> R) -> R { + let off = self.offset; + match &self.kind { + PtrKind::Null => panic!("ub: null pointer"), + PtrKind::StackSingle(weak) | PtrKind::HeapSingle(weak) => { + assert!(off == 0 && len <= 1, "ub: with_slice_mut out of bounds"); + let rc = weak.upgrade().expect("ub: dangling pointer"); + let mut b = rc.borrow_mut(); + f(&mut std::slice::from_mut(&mut *b)[..len]) + } + PtrKind::StackArray(weak) | PtrKind::HeapArray(weak) => { + let rc = weak.upgrade().expect("ub: dangling pointer"); + let mut b = rc.borrow_mut(); + f(&mut b[off..off + len]) + } + PtrKind::Vec(weak) => { + let rc = weak.upgrade().expect("ub: dangling pointer"); + let mut b = rc.borrow_mut(); + f(&mut b[off..off + len]) + } + PtrKind::Reinterpreted(data) => { + let mut buf = vec![0u8; len]; + data.alloc.read_bytes(off, &mut buf); + let r = f(&mut buf); + data.alloc.write_bytes(off, &buf); + r + } + } + } + + pub fn with_slice(&self, len: usize, f: impl FnOnce(&[u8]) -> R) -> R { + let off = self.offset; + match &self.kind { + PtrKind::Null => panic!("ub: null pointer"), + PtrKind::StackSingle(weak) | PtrKind::HeapSingle(weak) => { + assert!(off == 0 && len <= 1, "ub: with_slice out of bounds"); + let rc = weak.upgrade().expect("ub: dangling pointer"); + let b = rc.borrow(); + f(&std::slice::from_ref(&*b)[..len]) + } + PtrKind::StackArray(weak) | PtrKind::HeapArray(weak) => { + let rc = weak.upgrade().expect("ub: dangling pointer"); + let b = rc.borrow(); + f(&b[off..off + len]) + } + PtrKind::Vec(weak) => { + let rc = weak.upgrade().expect("ub: dangling pointer"); + let b = rc.borrow(); + f(&b[off..off + len]) + } + PtrKind::Reinterpreted(data) => { + let mut buf = vec![0u8; len]; + data.alloc.read_bytes(off, &mut buf); + f(&buf) + } + } + } + #[allow(clippy::explicit_counter_loop)] pub fn memcpy(&self, src: &Self, len: usize) { let mut dst = self.clone(); diff --git a/rules/socket/tgt_refcount.rs b/rules/socket/tgt_refcount.rs index 8b1f7cd0..5d591a14 100644 --- a/rules/socket/tgt_refcount.rs +++ b/rules/socket/tgt_refcount.rs @@ -14,3 +14,29 @@ fn t2() -> libcc2rs::SockaddrStorage { fn t3() -> libcc2rs::SockaddrUn { Default::default() } + +fn f9(a0: i32, a1: AnyPtr, a2: usize, a3: i32) -> isize { + let __buf = a1.reinterpret_cast::(); + match __buf.with_slice_mut(a2, |__s| { + nix::sys::socket::recv(a0, __s, nix::sys::socket::MsgFlags::from_bits_truncate(a3)) + }) { + Ok(__n) => __n as isize, + Err(__e) => { + libcc2rs::cpp2rust_errno().write(__e as i32); + -1 + } + } +} + +fn f10(a0: i32, a1: AnyPtr, a2: usize, a3: i32) -> isize { + let __buf = a1.reinterpret_cast::(); + match __buf.with_slice(a2, |__s| { + nix::sys::socket::send(a0, __s, nix::sys::socket::MsgFlags::from_bits_truncate(a3)) + }) { + Ok(__n) => __n as isize, + Err(__e) => { + libcc2rs::cpp2rust_errno().write(__e as i32); + -1 + } + } +}