From 6d4722504e537a114a4ca3edfbb9af973ee4be24 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Wed, 8 Jul 2026 11:21:04 +0100 Subject: [PATCH 1/8] Add rules for libc structs --- rules/dirent/src.cpp | 1 + rules/dirent/tgt_unsafe.rs | 4 +++ rules/ifaddrs/src.cpp | 2 ++ rules/ifaddrs/tgt_unsafe.rs | 4 +++ rules/ip/src.cpp | 5 +++ rules/ip/tgt_unsafe.rs | 16 +++++++++ rules/netdb/src.cpp | 2 ++ rules/netdb/tgt_unsafe.rs | 4 +++ rules/poll/src.cpp | 2 ++ rules/poll/tgt_unsafe.rs | 4 +++ rules/pwd/src.cpp | 2 ++ rules/pwd/tgt_unsafe.rs | 4 +++ rules/socket/src.c | 3 ++ rules/socket/tgt_unsafe.rs | 8 +++++ rules/stat/src.cpp | 2 ++ rules/stat/tgt_unsafe.rs | 4 +++ rules/termios/src.cpp | 4 +++ rules/termios/tgt_unsafe.rs | 8 +++++ rules/time/src.c | 4 +++ rules/time/tgt_unsafe.rs | 12 +++++++ .../out/refcount/socket_transparent_union.rs | 33 +++++++++++++++++++ tests/unit/out/unsafe/libc_char_ptr_field.rs | 4 +-- .../out/unsafe/libc_struct_without_default.rs | 8 ++--- .../out/unsafe/socket_transparent_union.rs | 12 +++---- tests/unit/out/unsafe/sys_stat.rs | 8 ++--- tests/unit/socket_transparent_union.c | 2 +- 26 files changed, 145 insertions(+), 17 deletions(-) create mode 100644 tests/unit/out/refcount/socket_transparent_union.rs diff --git a/rules/dirent/src.cpp b/rules/dirent/src.cpp index 9f76ffba..f5b720e1 100644 --- a/rules/dirent/src.cpp +++ b/rules/dirent/src.cpp @@ -4,6 +4,7 @@ #include using t1 = DIR *; +using t2 = struct dirent; DIR *f1(const char *name) { return opendir(name); } diff --git a/rules/dirent/tgt_unsafe.rs b/rules/dirent/tgt_unsafe.rs index 602fa429..da80489d 100644 --- a/rules/dirent/tgt_unsafe.rs +++ b/rules/dirent/tgt_unsafe.rs @@ -5,6 +5,10 @@ fn t1() -> *mut ::libc::DIR { std::ptr::null_mut() } +fn t2() -> ::libc::dirent { + unsafe { std::mem::zeroed() } +} + unsafe fn f1(a0: *const libc::c_char) -> *mut ::libc::DIR { libc::opendir(a0) } diff --git a/rules/ifaddrs/src.cpp b/rules/ifaddrs/src.cpp index 8e699671..ae5d8655 100644 --- a/rules/ifaddrs/src.cpp +++ b/rules/ifaddrs/src.cpp @@ -1,6 +1,8 @@ #include #include +typedef struct ifaddrs t1; + int f1(struct ifaddrs **ifap) { return getifaddrs(ifap); } diff --git a/rules/ifaddrs/tgt_unsafe.rs b/rules/ifaddrs/tgt_unsafe.rs index 6ab1ad75..327bc341 100644 --- a/rules/ifaddrs/tgt_unsafe.rs +++ b/rules/ifaddrs/tgt_unsafe.rs @@ -1,3 +1,7 @@ +fn t1() -> libc::ifaddrs { + unsafe { std::mem::zeroed() } +} + unsafe fn f1(a0: *mut *mut libc::ifaddrs) -> i32 { libc::getifaddrs(a0) } diff --git a/rules/ip/src.cpp b/rules/ip/src.cpp index 1fabb8b2..ca5b4a4b 100644 --- a/rules/ip/src.cpp +++ b/rules/ip/src.cpp @@ -1,5 +1,10 @@ #include +typedef struct sockaddr_in t1; +typedef struct in_addr t2; +typedef struct sockaddr_in6 t3; +typedef struct in6_addr t4; + int f1() { return IPPROTO_TCP; } diff --git a/rules/ip/tgt_unsafe.rs b/rules/ip/tgt_unsafe.rs index ff300a25..7dd3988a 100644 --- a/rules/ip/tgt_unsafe.rs +++ b/rules/ip/tgt_unsafe.rs @@ -1,3 +1,19 @@ +fn t1() -> ::libc::sockaddr_in { + unsafe { std::mem::zeroed() } +} + +fn t2() -> ::libc::in_addr { + unsafe { std::mem::zeroed() } +} + +fn t3() -> ::libc::sockaddr_in6 { + unsafe { std::mem::zeroed() } +} + +fn t4() -> ::libc::in6_addr { + unsafe { std::mem::zeroed() } +} + unsafe fn f1() -> i32 { libc::IPPROTO_TCP } diff --git a/rules/netdb/src.cpp b/rules/netdb/src.cpp index be8e42c9..ad0ccd2e 100644 --- a/rules/netdb/src.cpp +++ b/rules/netdb/src.cpp @@ -3,6 +3,8 @@ #include +typedef struct addrinfo t1; + int f1(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res) { return getaddrinfo(node, service, hints, res); diff --git a/rules/netdb/tgt_unsafe.rs b/rules/netdb/tgt_unsafe.rs index d1f74394..76b29217 100644 --- a/rules/netdb/tgt_unsafe.rs +++ b/rules/netdb/tgt_unsafe.rs @@ -1,6 +1,10 @@ // Copyright (c) 2022-present INESC-ID. // Distributed under the MIT license that can be found in the LICENSE file. +fn t1() -> ::libc::addrinfo { + unsafe { std::mem::zeroed() } +} + unsafe fn f1( a0: *const libc::c_char, a1: *const libc::c_char, diff --git a/rules/poll/src.cpp b/rules/poll/src.cpp index 06deebd6..58f5b7dd 100644 --- a/rules/poll/src.cpp +++ b/rules/poll/src.cpp @@ -3,6 +3,8 @@ #include +typedef struct pollfd t1; + int f1(struct pollfd *fds, nfds_t nfds, int timeout) { return poll(fds, nfds, timeout); } diff --git a/rules/poll/tgt_unsafe.rs b/rules/poll/tgt_unsafe.rs index 34ded1fd..97ff38ae 100644 --- a/rules/poll/tgt_unsafe.rs +++ b/rules/poll/tgt_unsafe.rs @@ -1,6 +1,10 @@ // Copyright (c) 2022-present INESC-ID. // Distributed under the MIT license that can be found in the LICENSE file. +fn t1() -> ::libc::pollfd { + unsafe { std::mem::zeroed() } +} + unsafe fn f1(a0: *mut ::libc::pollfd, a1: u64, a2: i32) -> i32 { libc::poll(a0, a1 as ::libc::nfds_t, a2) } diff --git a/rules/pwd/src.cpp b/rules/pwd/src.cpp index e398ff71..12dbd3ee 100644 --- a/rules/pwd/src.cpp +++ b/rules/pwd/src.cpp @@ -3,6 +3,8 @@ #include +typedef struct passwd t1; + struct passwd *f1(uid_t uid) { return getpwuid(uid); } int f2(uid_t uid, struct passwd *pwd, char *buf, size_t buflen, diff --git a/rules/pwd/tgt_unsafe.rs b/rules/pwd/tgt_unsafe.rs index d20596f9..dffa7018 100644 --- a/rules/pwd/tgt_unsafe.rs +++ b/rules/pwd/tgt_unsafe.rs @@ -1,6 +1,10 @@ // Copyright (c) 2022-present INESC-ID. // Distributed under the MIT license that can be found in the LICENSE file. +fn t1() -> ::libc::passwd { + unsafe { std::mem::zeroed() } +} + unsafe fn f1(a0: u32) -> *mut ::libc::passwd { libc::getpwuid(a0) } diff --git a/rules/socket/src.c b/rules/socket/src.c index ca290b1d..243e2463 100644 --- a/rules/socket/src.c +++ b/rules/socket/src.c @@ -1,8 +1,11 @@ #define _GNU_SOURCE #include #include +#include typedef struct sockaddr t1; +typedef struct sockaddr_storage t2; +typedef struct sockaddr_un t3; int f1() { return MSG_NOSIGNAL; diff --git a/rules/socket/tgt_unsafe.rs b/rules/socket/tgt_unsafe.rs index f263d8c5..7b93c687 100644 --- a/rules/socket/tgt_unsafe.rs +++ b/rules/socket/tgt_unsafe.rs @@ -2,6 +2,14 @@ fn t1() -> libc::sockaddr { unsafe { std::mem::zeroed() } } +fn t2() -> libc::sockaddr_storage { + unsafe { std::mem::zeroed() } +} + +fn t3() -> libc::sockaddr_un { + unsafe { std::mem::zeroed() } +} + unsafe fn f1() -> i32 { libc::MSG_NOSIGNAL } diff --git a/rules/stat/src.cpp b/rules/stat/src.cpp index 960278a9..5d79dfda 100644 --- a/rules/stat/src.cpp +++ b/rules/stat/src.cpp @@ -3,6 +3,8 @@ #include +typedef struct stat t1; + int f1(const char *pathname, struct stat *statbuf) { return stat(pathname, statbuf); } diff --git a/rules/stat/tgt_unsafe.rs b/rules/stat/tgt_unsafe.rs index 5d0f9703..c6da0a5a 100644 --- a/rules/stat/tgt_unsafe.rs +++ b/rules/stat/tgt_unsafe.rs @@ -1,6 +1,10 @@ // Copyright (c) 2022-present INESC-ID. // Distributed under the MIT license that can be found in the LICENSE file. +fn t1() -> ::libc::stat { + unsafe { std::mem::zeroed() } +} + unsafe fn f1(a0: *const libc::c_char, a1: *mut ::libc::stat) -> i32 { libc::stat(a0, a1) } diff --git a/rules/termios/src.cpp b/rules/termios/src.cpp index 32f014bf..51162526 100644 --- a/rules/termios/src.cpp +++ b/rules/termios/src.cpp @@ -2,6 +2,10 @@ // Distributed under the MIT license that can be found in the LICENSE file. #include +#include + +typedef struct termios t1; +typedef struct winsize t2; int f1(int fd, int optional_actions, const struct termios *termios_p) { return tcsetattr(fd, optional_actions, termios_p); diff --git a/rules/termios/tgt_unsafe.rs b/rules/termios/tgt_unsafe.rs index 1d40338d..32375af9 100644 --- a/rules/termios/tgt_unsafe.rs +++ b/rules/termios/tgt_unsafe.rs @@ -1,6 +1,14 @@ // Copyright (c) 2022-present INESC-ID. // Distributed under the MIT license that can be found in the LICENSE file. +fn t1() -> ::libc::termios { + unsafe { std::mem::zeroed() } +} + +fn t2() -> ::libc::winsize { + unsafe { std::mem::zeroed() } +} + unsafe fn f1(a0: i32, a1: i32, a2: *const ::libc::termios) -> i32 { libc::tcsetattr(a0, a1, a2) } diff --git a/rules/time/src.c b/rules/time/src.c index 6a7f2e7c..270bf646 100644 --- a/rules/time/src.c +++ b/rules/time/src.c @@ -4,6 +4,10 @@ #include #include +typedef struct tm t1; +typedef struct timeval t2; +typedef struct timespec t3; + time_t f1(time_t *t) { return time(t); } int f2(clockid_t clk_id, struct timespec *tp) { diff --git a/rules/time/tgt_unsafe.rs b/rules/time/tgt_unsafe.rs index add3a6a0..0f8c1cd5 100644 --- a/rules/time/tgt_unsafe.rs +++ b/rules/time/tgt_unsafe.rs @@ -1,6 +1,18 @@ // Copyright (c) 2022-present INESC-ID. // Distributed under the MIT license that can be found in the LICENSE file. +fn t1() -> ::libc::tm { + unsafe { std::mem::zeroed() } +} + +fn t2() -> ::libc::timeval { + unsafe { std::mem::zeroed() } +} + +fn t3() -> ::libc::timespec { + unsafe { std::mem::zeroed() } +} + unsafe fn f1(a0: *mut ::libc::time_t) -> ::libc::time_t { libc::time(a0) } diff --git a/tests/unit/out/refcount/socket_transparent_union.rs b/tests/unit/out/refcount/socket_transparent_union.rs new file mode 100644 index 00000000..35ebf4f3 --- /dev/null +++ b/tests/unit/out/refcount/socket_transparent_union.rs @@ -0,0 +1,33 @@ +extern crate libcc2rs; +use libcc2rs::*; +use std::cell::RefCell; +use std::collections::BTreeMap; +use std::io::prelude::*; +use std::io::{Read, Seek, Write}; +use std::os::fd::AsFd; +use std::rc::{Rc, Weak}; +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let fd: Value = Rc::new(RefCell::new(0)); + let ssloc: Value = Rc::new(RefCell::new(unsafe { std::mem::zeroed() })); + let slen: Value = Rc::new(RefCell::new((128usize as u32))); + assert!( + ((({ + let result: i32 = todo!("getsockname is not implemented yet"); + result + } == -1_i32) as i32) + != 0) + ); + let sin: Value<::libc::sockaddr_in> = Rc::new(RefCell::new(unsafe { std::mem::zeroed() })); + let inlen: Value = Rc::new(RefCell::new((16usize as u32))); + assert!( + ((({ + let result: i32 = todo!("getsockname is not implemented yet"); + result + } == -1_i32) as i32) + != 0) + ); + return 0; +} diff --git a/tests/unit/out/unsafe/libc_char_ptr_field.rs b/tests/unit/out/unsafe/libc_char_ptr_field.rs index 603e3730..8d44f5b0 100644 --- a/tests/unit/out/unsafe/libc_char_ptr_field.rs +++ b/tests/unit/out/unsafe/libc_char_ptr_field.rs @@ -12,12 +12,12 @@ pub fn main() { } } unsafe fn main_0() -> i32 { - let mut pw: *mut passwd = libc::getpwuid(libc::geteuid()); + let mut pw: *mut ::libc::passwd = libc::getpwuid(libc::geteuid()); if !!(pw).is_null() { return 0; } let mut home: *mut libc::c_char = (*pw).pw_dir; - let mut d: *mut dirent = + let mut d: *mut ::libc::dirent = libc::readdir(libc::opendir((c"/tmp".as_ptr().cast_mut()).cast_const())); let mut dname: *mut libc::c_char = (*d).d_name.as_mut_ptr(); return 0; diff --git a/tests/unit/out/unsafe/libc_struct_without_default.rs b/tests/unit/out/unsafe/libc_struct_without_default.rs index 7dd5b896..45147dbc 100644 --- a/tests/unit/out/unsafe/libc_struct_without_default.rs +++ b/tests/unit/out/unsafe/libc_struct_without_default.rs @@ -38,24 +38,24 @@ pub fn main() { } } unsafe fn main_0() -> i32 { - let mut p: pollfd = unsafe { std::mem::zeroed::() }; + let mut p: ::libc::pollfd = unsafe { std::mem::zeroed() }; p.fd = -1_i32; p.events = 0_i16; p.revents = 2_i16; assert!(((p.fd) == (-1_i32))); assert!(((p.events as i32) == (0))); assert!(((p.revents as i32) == (2))); - let mut ia: in_addr = unsafe { std::mem::zeroed::() }; + let mut ia: ::libc::in_addr = unsafe { std::mem::zeroed() }; ia.s_addr = 1_u32; assert!(((ia.s_addr) == (1_u32))); - let mut t: tm = unsafe { std::mem::zeroed::() }; + let mut t: ::libc::tm = unsafe { std::mem::zeroed() }; t.tm_year = 124; t.tm_mon = 5; t.tm_mday = 15; assert!(((t.tm_year) == (124))); assert!(((t.tm_mon) == (5))); assert!(((t.tm_mday) == (15))); - let mut st: stat = unsafe { std::mem::zeroed::() }; + let mut st: ::libc::stat = unsafe { std::mem::zeroed() }; st.st_size = 1024_i64; assert!(((st.st_size) == (1024_i64))); let mut ud: UserDefined = ::default(); diff --git a/tests/unit/out/unsafe/socket_transparent_union.rs b/tests/unit/out/unsafe/socket_transparent_union.rs index 910ec07a..2bada880 100644 --- a/tests/unit/out/unsafe/socket_transparent_union.rs +++ b/tests/unit/out/unsafe/socket_transparent_union.rs @@ -13,22 +13,22 @@ pub fn main() { } unsafe fn main_0() -> i32 { let mut fd: i32 = 0; - let mut ssloc: sockaddr_storage = unsafe { std::mem::zeroed::() }; - let mut slen: u32 = (::std::mem::size_of::() as u32); + let mut ssloc: libc::sockaddr_storage = unsafe { std::mem::zeroed() }; + let mut slen: u32 = (::std::mem::size_of::() as u32); assert!( ((((libc::getsockname( fd, - ((&mut ssloc as *mut sockaddr_storage) as *mut libc::sockaddr), + ((&mut ssloc as *mut libc::sockaddr_storage) as *mut libc::sockaddr), (&mut slen as *mut u32) )) == (-1_i32)) as i32) != 0) ); - let mut sin: sockaddr_in = unsafe { std::mem::zeroed::() }; - let mut inlen: u32 = (::std::mem::size_of::() as u32); + let mut sin: ::libc::sockaddr_in = unsafe { std::mem::zeroed() }; + let mut inlen: u32 = (::std::mem::size_of::<::libc::sockaddr_in>() as u32); assert!( ((((libc::getsockname( fd, - ((&mut sin as *mut sockaddr_in) as *mut libc::sockaddr), + ((&mut sin as *mut ::libc::sockaddr_in) as *mut libc::sockaddr), (&mut inlen as *mut u32) )) == (-1_i32)) as i32) != 0) diff --git a/tests/unit/out/unsafe/sys_stat.rs b/tests/unit/out/unsafe/sys_stat.rs index 89445d13..d3d00d9b 100644 --- a/tests/unit/out/unsafe/sys_stat.rs +++ b/tests/unit/out/unsafe/sys_stat.rs @@ -13,8 +13,8 @@ pub unsafe fn test_stat_0() { assert!((((!((fp).is_null())) as i32) != 0)); libc::fputs((c"hello".as_ptr().cast_mut()).cast_const(), fp); assert!(((((libc::fclose(fp)) == (0)) as i32) != 0)); - let mut st: stat = unsafe { std::mem::zeroed::() }; - assert!(((((libc::stat(path, (&mut st as *mut stat))) == (0)) as i32) != 0)); + let mut st: ::libc::stat = unsafe { std::mem::zeroed() }; + assert!(((((libc::stat(path, (&mut st as *mut ::libc::stat))) == (0)) as i32) != 0)); assert!(((((st.st_size) == (5_i64)) as i32) != 0)); assert!(((((st.st_mtime) > (0_i64)) as i32) != 0)); libc::unlink(path); @@ -27,8 +27,8 @@ pub unsafe fn test_fstat_1() { libc::fputs((c"hello world".as_ptr().cast_mut()).cast_const(), fp); libc::fflush(fp); let mut fd: i32 = libc::fileno(fp); - let mut st: stat = unsafe { std::mem::zeroed::() }; - assert!(((((libc::fstat(fd, (&mut st as *mut stat))) == (0)) as i32) != 0)); + let mut st: ::libc::stat = unsafe { std::mem::zeroed() }; + assert!(((((libc::fstat(fd, (&mut st as *mut ::libc::stat))) == (0)) as i32) != 0)); assert!(((((st.st_size) == (11_i64)) as i32) != 0)); assert!(((((st.st_mtime) > (0_i64)) as i32) != 0)); assert!(((((libc::fclose(fp)) == (0)) as i32) != 0)); diff --git a/tests/unit/socket_transparent_union.c b/tests/unit/socket_transparent_union.c index 7ee4b865..7ebeb76e 100644 --- a/tests/unit/socket_transparent_union.c +++ b/tests/unit/socket_transparent_union.c @@ -1,4 +1,4 @@ -// no-compile: refcount +// panic: refcount #define _GNU_SOURCE #include #include From 0adcaca7cc056c69877e151857c88067abccbe95 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Tue, 14 Jul 2026 23:52:49 +0100 Subject: [PATCH 2/8] Update tests --- .../out/refcount/socket_transparent_union.rs | 18 ++++++++++-------- tests/unit/socket_transparent_union.c | 2 +- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/tests/unit/out/refcount/socket_transparent_union.rs b/tests/unit/out/refcount/socket_transparent_union.rs index 35ebf4f3..95abf6ff 100644 --- a/tests/unit/out/refcount/socket_transparent_union.rs +++ b/tests/unit/out/refcount/socket_transparent_union.rs @@ -14,19 +14,21 @@ fn main_0() -> i32 { let ssloc: Value = Rc::new(RefCell::new(unsafe { std::mem::zeroed() })); let slen: Value = Rc::new(RefCell::new((128usize as u32))); assert!( - ((({ - let result: i32 = todo!("getsockname is not implemented yet"); - result - } == -1_i32) as i32) + (((libc::getsockname( + (*fd.borrow()), + (ssloc.as_pointer()).reinterpret_cast::(), + (slen.as_pointer()) + ) == -1_i32) as i32) != 0) ); let sin: Value<::libc::sockaddr_in> = Rc::new(RefCell::new(unsafe { std::mem::zeroed() })); let inlen: Value = Rc::new(RefCell::new((16usize as u32))); assert!( - ((({ - let result: i32 = todo!("getsockname is not implemented yet"); - result - } == -1_i32) as i32) + (((libc::getsockname( + (*fd.borrow()), + (sin.as_pointer()).reinterpret_cast::(), + (inlen.as_pointer()) + ) == -1_i32) as i32) != 0) ); return 0; diff --git a/tests/unit/socket_transparent_union.c b/tests/unit/socket_transparent_union.c index 7ebeb76e..7ee4b865 100644 --- a/tests/unit/socket_transparent_union.c +++ b/tests/unit/socket_transparent_union.c @@ -1,4 +1,4 @@ -// panic: refcount +// no-compile: refcount #define _GNU_SOURCE #include #include From b0296fbd50d277e7c113cf26746af02669574712 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Tue, 14 Jul 2026 23:53:30 +0100 Subject: [PATCH 3/8] Delete irrelevant file --- .../out/refcount/socket_transparent_union.rs | 35 ------------------- 1 file changed, 35 deletions(-) delete mode 100644 tests/unit/out/refcount/socket_transparent_union.rs diff --git a/tests/unit/out/refcount/socket_transparent_union.rs b/tests/unit/out/refcount/socket_transparent_union.rs deleted file mode 100644 index 95abf6ff..00000000 --- a/tests/unit/out/refcount/socket_transparent_union.rs +++ /dev/null @@ -1,35 +0,0 @@ -extern crate libcc2rs; -use libcc2rs::*; -use std::cell::RefCell; -use std::collections::BTreeMap; -use std::io::prelude::*; -use std::io::{Read, Seek, Write}; -use std::os::fd::AsFd; -use std::rc::{Rc, Weak}; -pub fn main() { - std::process::exit(main_0()); -} -fn main_0() -> i32 { - let fd: Value = Rc::new(RefCell::new(0)); - let ssloc: Value = Rc::new(RefCell::new(unsafe { std::mem::zeroed() })); - let slen: Value = Rc::new(RefCell::new((128usize as u32))); - assert!( - (((libc::getsockname( - (*fd.borrow()), - (ssloc.as_pointer()).reinterpret_cast::(), - (slen.as_pointer()) - ) == -1_i32) as i32) - != 0) - ); - let sin: Value<::libc::sockaddr_in> = Rc::new(RefCell::new(unsafe { std::mem::zeroed() })); - let inlen: Value = Rc::new(RefCell::new((16usize as u32))); - assert!( - (((libc::getsockname( - (*fd.borrow()), - (sin.as_pointer()).reinterpret_cast::(), - (inlen.as_pointer()) - ) == -1_i32) as i32) - != 0) - ); - return 0; -} From 358ea1b58ae3203c7d5e2bdc80a4f29e76fc70d0 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Wed, 15 Jul 2026 09:36:45 +0100 Subject: [PATCH 4/8] Add refcount shims for libc structs --- libcc2rs/src/libc_shims/dirent.rs | 49 +++++ libcc2rs/src/libc_shims/ifaddrs.rs | 43 ++++ libcc2rs/src/libc_shims/ip.rs | 76 +++++++ libcc2rs/src/libc_shims/mod.rs | 26 +++ libcc2rs/src/libc_shims/netdb.rs | 52 +++++ libcc2rs/src/libc_shims/poll.rs | 36 ++++ libcc2rs/src/libc_shims/pwd.rs | 48 +++++ libcc2rs/src/libc_shims/socket.rs | 331 +++++++++++++++++++++++++++++ libcc2rs/src/libc_shims/stat.rs | 86 ++++++++ libcc2rs/src/libc_shims/termios.rs | 80 +++++++ libcc2rs/src/libc_shims/time.rs | 112 ++++++++++ 11 files changed, 939 insertions(+) create mode 100644 libcc2rs/src/libc_shims/dirent.rs create mode 100644 libcc2rs/src/libc_shims/ifaddrs.rs create mode 100644 libcc2rs/src/libc_shims/ip.rs create mode 100644 libcc2rs/src/libc_shims/mod.rs create mode 100644 libcc2rs/src/libc_shims/netdb.rs create mode 100644 libcc2rs/src/libc_shims/poll.rs create mode 100644 libcc2rs/src/libc_shims/pwd.rs create mode 100644 libcc2rs/src/libc_shims/socket.rs create mode 100644 libcc2rs/src/libc_shims/stat.rs create mode 100644 libcc2rs/src/libc_shims/termios.rs create mode 100644 libcc2rs/src/libc_shims/time.rs diff --git a/libcc2rs/src/libc_shims/dirent.rs b/libcc2rs/src/libc_shims/dirent.rs new file mode 100644 index 00000000..bfdb0a4e --- /dev/null +++ b/libcc2rs/src/libc_shims/dirent.rs @@ -0,0 +1,49 @@ +// Copyright (c) 2022-present INESC-ID. +// Distributed under the MIT license that can be found in the LICENSE file. + +use crate::{ByteRepr, Value}; +use std::cell::RefCell; +use std::rc::Rc; + +pub struct dirent { + pub d_ino: Value, + pub d_off: Value, + pub d_reclen: Value, + pub d_type: Value, + pub d_name: Value>, +} + +impl Default for dirent { + fn default() -> Self { + Self { + d_ino: Rc::new(RefCell::new(0)), + d_off: Rc::new(RefCell::new(0)), + d_reclen: Rc::new(RefCell::new(0)), + d_type: Rc::new(RefCell::new(0)), + d_name: Rc::new(RefCell::new(vec![0u8; 256].into_boxed_slice())), + } + } +} + +impl Clone for dirent { + fn clone(&self) -> Self { + Self { + d_ino: Rc::new(RefCell::new(*self.d_ino.borrow())), + d_off: Rc::new(RefCell::new(*self.d_off.borrow())), + d_reclen: Rc::new(RefCell::new(*self.d_reclen.borrow())), + d_type: Rc::new(RefCell::new(*self.d_type.borrow())), + d_name: Rc::new(RefCell::new(self.d_name.borrow().clone())), + } + } +} + +impl ByteRepr for dirent {} + +pub struct CDir { + pub entries: Vec<(u64, Vec, u8)>, + pub pos: ::std::cell::Cell, +} + +impl ByteRepr for CDir {} + +impl ByteRepr for ::libc::dirent {} diff --git a/libcc2rs/src/libc_shims/ifaddrs.rs b/libcc2rs/src/libc_shims/ifaddrs.rs new file mode 100644 index 00000000..e6e4cf3f --- /dev/null +++ b/libcc2rs/src/libc_shims/ifaddrs.rs @@ -0,0 +1,43 @@ +// Copyright (c) 2022-present INESC-ID. +// Distributed under the MIT license that can be found in the LICENSE file. + +use super::sockaddr; +use crate::{ByteRepr, Ptr, Value}; +use std::cell::RefCell; +use std::rc::Rc; + +pub struct ifaddrs { + pub ifa_next: Value>, + pub ifa_name: Value>, + pub ifa_flags: Value, + pub ifa_addr: Value>, + pub ifa_netmask: Value>, +} + +impl Default for ifaddrs { + fn default() -> Self { + Self { + ifa_next: Rc::new(RefCell::new(Ptr::null())), + ifa_name: Rc::new(RefCell::new(Ptr::null())), + ifa_flags: Rc::new(RefCell::new(0)), + ifa_addr: Rc::new(RefCell::new(Ptr::null())), + ifa_netmask: Rc::new(RefCell::new(Ptr::null())), + } + } +} + +impl Clone for ifaddrs { + fn clone(&self) -> Self { + Self { + ifa_next: Rc::new(RefCell::new(self.ifa_next.borrow().clone())), + ifa_name: Rc::new(RefCell::new(self.ifa_name.borrow().clone())), + ifa_flags: Rc::new(RefCell::new(*self.ifa_flags.borrow())), + ifa_addr: Rc::new(RefCell::new(self.ifa_addr.borrow().clone())), + ifa_netmask: Rc::new(RefCell::new(self.ifa_netmask.borrow().clone())), + } + } +} + +impl ByteRepr for ifaddrs {} + +impl ByteRepr for ::libc::ifaddrs {} diff --git a/libcc2rs/src/libc_shims/ip.rs b/libcc2rs/src/libc_shims/ip.rs new file mode 100644 index 00000000..1d6b45e7 --- /dev/null +++ b/libcc2rs/src/libc_shims/ip.rs @@ -0,0 +1,76 @@ +// Copyright (c) 2022-present INESC-ID. +// Distributed under the MIT license that can be found in the LICENSE file. + +use crate::{AsPointer, ByteRepr, Ptr, Value}; +use std::cell::RefCell; +use std::rc::Rc; + +#[derive(Default)] +pub struct in_addr { + pub s_addr: Value, +} + +pub struct in6_addr { + pub s6_addr: Value>, +} + +impl in6_addr { + pub fn s6_addr(&self) -> Ptr { + self.s6_addr.as_pointer() + } +} + +impl Default for in6_addr { + fn default() -> Self { + Self { + s6_addr: Rc::new(RefCell::new(vec![0u8; 16].into_boxed_slice())), + } + } +} + +impl Clone for in_addr { + fn clone(&self) -> Self { + Self { + s_addr: Rc::new(RefCell::new(*self.s_addr.borrow())), + } + } +} + +impl Clone for in6_addr { + fn clone(&self) -> Self { + Self { + s6_addr: Rc::new(RefCell::new(self.s6_addr.borrow().clone())), + } + } +} + +impl ByteRepr for in_addr { + fn byte_size() -> usize { + 4 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.s_addr.borrow()).to_bytes(&mut buf[0..4]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + s_addr: Rc::new(RefCell::new(::from_bytes(&buf[0..4]))), + } + } +} + +impl ByteRepr for in6_addr { + fn byte_size() -> usize { + 16 + } + fn to_bytes(&self, buf: &mut [u8]) { + buf[0..16].copy_from_slice(&self.s6_addr.borrow()); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + s6_addr: Rc::new(RefCell::new(buf[0..16].to_vec().into_boxed_slice())), + } + } +} + +impl ByteRepr for ::libc::in_addr {} +impl ByteRepr for ::libc::in6_addr {} diff --git a/libcc2rs/src/libc_shims/mod.rs b/libcc2rs/src/libc_shims/mod.rs new file mode 100644 index 00000000..1ef02870 --- /dev/null +++ b/libcc2rs/src/libc_shims/mod.rs @@ -0,0 +1,26 @@ +// Copyright (c) 2022-present INESC-ID. +// Distributed under the MIT license that can be found in the LICENSE file. + +#![allow(non_camel_case_types)] + +mod dirent; +mod ifaddrs; +mod ip; +mod netdb; +mod poll; +mod pwd; +mod socket; +mod stat; +mod termios; +mod time; + +pub use dirent::*; +pub use ifaddrs::*; +pub use ip::*; +pub use netdb::*; +pub use poll::*; +pub use pwd::*; +pub use socket::*; +pub use stat::*; +pub use termios::*; +pub use time::*; diff --git a/libcc2rs/src/libc_shims/netdb.rs b/libcc2rs/src/libc_shims/netdb.rs new file mode 100644 index 00000000..efbaf5be --- /dev/null +++ b/libcc2rs/src/libc_shims/netdb.rs @@ -0,0 +1,52 @@ +// Copyright (c) 2022-present INESC-ID. +// Distributed under the MIT license that can be found in the LICENSE file. + +use super::sockaddr; +use crate::{ByteRepr, Ptr, Value}; +use std::cell::RefCell; +use std::rc::Rc; + +pub struct addrinfo { + pub ai_flags: Value, + pub ai_family: Value, + pub ai_socktype: Value, + pub ai_protocol: Value, + pub ai_addrlen: Value, + pub ai_addr: Value>, + pub ai_canonname: Value>, + pub ai_next: Value>, +} + +impl Default for addrinfo { + fn default() -> Self { + Self { + ai_flags: Rc::new(RefCell::new(0)), + ai_family: Rc::new(RefCell::new(0)), + ai_socktype: Rc::new(RefCell::new(0)), + ai_protocol: Rc::new(RefCell::new(0)), + ai_addrlen: Rc::new(RefCell::new(0)), + ai_addr: Rc::new(RefCell::new(Ptr::null())), + ai_canonname: Rc::new(RefCell::new(Ptr::null())), + ai_next: Rc::new(RefCell::new(Ptr::null())), + } + } +} + +impl Clone for addrinfo { + fn clone(&self) -> Self { + Self { + ai_flags: Rc::new(RefCell::new(*self.ai_flags.borrow())), + ai_family: Rc::new(RefCell::new(*self.ai_family.borrow())), + ai_socktype: Rc::new(RefCell::new(*self.ai_socktype.borrow())), + ai_protocol: Rc::new(RefCell::new(*self.ai_protocol.borrow())), + ai_addrlen: Rc::new(RefCell::new(*self.ai_addrlen.borrow())), + ai_addr: Rc::new(RefCell::new(self.ai_addr.borrow().clone())), + ai_canonname: Rc::new(RefCell::new(self.ai_canonname.borrow().clone())), + ai_next: Rc::new(RefCell::new(self.ai_next.borrow().clone())), + } + } +} + +impl ByteRepr for addrinfo {} + +impl ByteRepr for ::libc::addrinfo {} diff --git a/libcc2rs/src/libc_shims/poll.rs b/libcc2rs/src/libc_shims/poll.rs new file mode 100644 index 00000000..9e782ff3 --- /dev/null +++ b/libcc2rs/src/libc_shims/poll.rs @@ -0,0 +1,36 @@ +// Copyright (c) 2022-present INESC-ID. +// Distributed under the MIT license that can be found in the LICENSE file. + +use crate::{ByteRepr, Value}; +use std::cell::RefCell; +use std::rc::Rc; + +pub struct pollfd { + pub fd: Value, + pub events: Value, + pub revents: Value, +} + +impl Default for pollfd { + fn default() -> Self { + Self { + fd: Rc::new(RefCell::new(0)), + events: Rc::new(RefCell::new(0)), + revents: Rc::new(RefCell::new(0)), + } + } +} + +impl Clone for pollfd { + fn clone(&self) -> Self { + Self { + fd: Rc::new(RefCell::new(*self.fd.borrow())), + events: Rc::new(RefCell::new(*self.events.borrow())), + revents: Rc::new(RefCell::new(*self.revents.borrow())), + } + } +} + +impl ByteRepr for pollfd {} + +impl ByteRepr for ::libc::pollfd {} diff --git a/libcc2rs/src/libc_shims/pwd.rs b/libcc2rs/src/libc_shims/pwd.rs new file mode 100644 index 00000000..9156eb7e --- /dev/null +++ b/libcc2rs/src/libc_shims/pwd.rs @@ -0,0 +1,48 @@ +// Copyright (c) 2022-present INESC-ID. +// Distributed under the MIT license that can be found in the LICENSE file. + +use crate::{ByteRepr, Ptr, Value}; +use std::cell::RefCell; +use std::rc::Rc; + +pub struct passwd { + pub pw_name: Value>, + pub pw_passwd: Value>, + pub pw_uid: Value, + pub pw_gid: Value, + pub pw_gecos: Value>, + pub pw_dir: Value>, + pub pw_shell: Value>, +} + +impl Default for passwd { + fn default() -> Self { + Self { + pw_name: Rc::new(RefCell::new(Ptr::null())), + pw_passwd: Rc::new(RefCell::new(Ptr::null())), + pw_uid: Rc::new(RefCell::new(0)), + pw_gid: Rc::new(RefCell::new(0)), + pw_gecos: Rc::new(RefCell::new(Ptr::null())), + pw_dir: Rc::new(RefCell::new(Ptr::null())), + pw_shell: Rc::new(RefCell::new(Ptr::null())), + } + } +} + +impl Clone for passwd { + fn clone(&self) -> Self { + Self { + pw_name: Rc::new(RefCell::new(self.pw_name.borrow().clone())), + pw_passwd: Rc::new(RefCell::new(self.pw_passwd.borrow().clone())), + pw_uid: Rc::new(RefCell::new(*self.pw_uid.borrow())), + pw_gid: Rc::new(RefCell::new(*self.pw_gid.borrow())), + pw_gecos: Rc::new(RefCell::new(self.pw_gecos.borrow().clone())), + pw_dir: Rc::new(RefCell::new(self.pw_dir.borrow().clone())), + pw_shell: Rc::new(RefCell::new(self.pw_shell.borrow().clone())), + } + } +} + +impl ByteRepr for passwd {} + +impl ByteRepr for ::libc::passwd {} diff --git a/libcc2rs/src/libc_shims/socket.rs b/libcc2rs/src/libc_shims/socket.rs new file mode 100644 index 00000000..4521c6c9 --- /dev/null +++ b/libcc2rs/src/libc_shims/socket.rs @@ -0,0 +1,331 @@ +// Copyright (c) 2022-present INESC-ID. +// Distributed under the MIT license that can be found in the LICENSE file. + +use super::{in6_addr, in_addr}; +use crate::{ByteRepr, Ptr, Value}; +use std::cell::RefCell; +use std::rc::Rc; + +pub struct sockaddr { + pub sa_family: Value, + pub sa_data: Value>, +} + +pub struct sockaddr_in { + pub sin_family: Value, + pub sin_port: Value, + pub sin_addr: Value, + pub sin_zero: Value>, +} + +pub struct sockaddr_in6 { + pub sin6_family: Value, + pub sin6_port: Value, + pub sin6_flowinfo: Value, + pub sin6_addr: Value, + pub sin6_scope_id: Value, +} + +pub struct sockaddr_un { + pub sun_family: Value, + pub sun_path: Value>, +} + +pub struct sockaddr_storage { + pub ss_family: Value, + pub __pad: Value>, +} + +impl Default for sockaddr { + fn default() -> Self { + Self { + sa_family: Rc::new(RefCell::new(0)), + sa_data: Rc::new(RefCell::new(vec![0u8; 14].into_boxed_slice())), + } + } +} + +impl Default for sockaddr_in { + fn default() -> Self { + Self { + sin_family: Rc::new(RefCell::new(0)), + sin_port: Rc::new(RefCell::new(0)), + sin_addr: Rc::new(RefCell::new(in_addr::default())), + sin_zero: Rc::new(RefCell::new(vec![0u8; 8].into_boxed_slice())), + } + } +} + +impl Default for sockaddr_in6 { + fn default() -> Self { + Self { + sin6_family: Rc::new(RefCell::new(0)), + sin6_port: Rc::new(RefCell::new(0)), + sin6_flowinfo: Rc::new(RefCell::new(0)), + sin6_addr: Rc::new(RefCell::new(in6_addr::default())), + sin6_scope_id: Rc::new(RefCell::new(0)), + } + } +} + +impl Default for sockaddr_un { + fn default() -> Self { + Self { + sun_family: Rc::new(RefCell::new(0)), + sun_path: Rc::new(RefCell::new(vec![0u8; 108].into_boxed_slice())), + } + } +} + +impl Default for sockaddr_storage { + fn default() -> Self { + Self { + ss_family: Rc::new(RefCell::new(0)), + __pad: Rc::new(RefCell::new(vec![0u8; 126].into_boxed_slice())), + } + } +} + +impl Clone for sockaddr { + fn clone(&self) -> Self { + Self { + sa_family: Rc::new(RefCell::new(*self.sa_family.borrow())), + sa_data: Rc::new(RefCell::new(self.sa_data.borrow().clone())), + } + } +} + +impl Clone for sockaddr_in { + fn clone(&self) -> Self { + Self { + sin_family: Rc::new(RefCell::new(*self.sin_family.borrow())), + sin_port: Rc::new(RefCell::new(*self.sin_port.borrow())), + sin_addr: Rc::new(RefCell::new(self.sin_addr.borrow().clone())), + sin_zero: Rc::new(RefCell::new(self.sin_zero.borrow().clone())), + } + } +} + +impl Clone for sockaddr_in6 { + fn clone(&self) -> Self { + Self { + sin6_family: Rc::new(RefCell::new(*self.sin6_family.borrow())), + sin6_port: Rc::new(RefCell::new(*self.sin6_port.borrow())), + sin6_flowinfo: Rc::new(RefCell::new(*self.sin6_flowinfo.borrow())), + sin6_addr: Rc::new(RefCell::new(self.sin6_addr.borrow().clone())), + sin6_scope_id: Rc::new(RefCell::new(*self.sin6_scope_id.borrow())), + } + } +} + +impl Clone for sockaddr_un { + fn clone(&self) -> Self { + Self { + sun_family: Rc::new(RefCell::new(*self.sun_family.borrow())), + sun_path: Rc::new(RefCell::new(self.sun_path.borrow().clone())), + } + } +} + +impl Clone for sockaddr_storage { + fn clone(&self) -> Self { + Self { + ss_family: Rc::new(RefCell::new(*self.ss_family.borrow())), + __pad: Rc::new(RefCell::new(self.__pad.borrow().clone())), + } + } +} + +impl ByteRepr for sockaddr { + fn byte_size() -> usize { + 16 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.sa_family.borrow()).to_bytes(&mut buf[0..2]); + buf[2..16].copy_from_slice(&self.sa_data.borrow()); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + sa_family: Rc::new(RefCell::new(::from_bytes(&buf[0..2]))), + sa_data: Rc::new(RefCell::new(buf[2..16].to_vec().into_boxed_slice())), + } + } +} + +impl ByteRepr for sockaddr_in { + fn byte_size() -> usize { + 16 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.sin_family.borrow()).to_bytes(&mut buf[0..2]); + (*self.sin_port.borrow()).to_bytes(&mut buf[2..4]); + (*self.sin_addr.borrow()).to_bytes(&mut buf[4..8]); + buf[8..16].copy_from_slice(&self.sin_zero.borrow()); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + sin_family: Rc::new(RefCell::new(::from_bytes(&buf[0..2]))), + sin_port: Rc::new(RefCell::new(::from_bytes(&buf[2..4]))), + sin_addr: Rc::new(RefCell::new(::from_bytes(&buf[4..8]))), + sin_zero: Rc::new(RefCell::new(buf[8..16].to_vec().into_boxed_slice())), + } + } +} + +impl ByteRepr for sockaddr_in6 { + fn byte_size() -> usize { + 28 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.sin6_family.borrow()).to_bytes(&mut buf[0..2]); + (*self.sin6_port.borrow()).to_bytes(&mut buf[2..4]); + (*self.sin6_flowinfo.borrow()).to_bytes(&mut buf[4..8]); + (*self.sin6_addr.borrow()).to_bytes(&mut buf[8..24]); + (*self.sin6_scope_id.borrow()).to_bytes(&mut buf[24..28]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + sin6_family: Rc::new(RefCell::new(::from_bytes(&buf[0..2]))), + sin6_port: Rc::new(RefCell::new(::from_bytes(&buf[2..4]))), + sin6_flowinfo: Rc::new(RefCell::new(::from_bytes(&buf[4..8]))), + sin6_addr: Rc::new(RefCell::new(::from_bytes(&buf[8..24]))), + sin6_scope_id: Rc::new(RefCell::new(::from_bytes(&buf[24..28]))), + } + } +} + +impl ByteRepr for sockaddr_un { + fn byte_size() -> usize { + 110 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.sun_family.borrow()).to_bytes(&mut buf[0..2]); + buf[2..110].copy_from_slice(&self.sun_path.borrow()); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + sun_family: Rc::new(RefCell::new(::from_bytes(&buf[0..2]))), + sun_path: Rc::new(RefCell::new(buf[2..110].to_vec().into_boxed_slice())), + } + } +} + +impl ByteRepr for sockaddr_storage { + fn byte_size() -> usize { + 128 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.ss_family.borrow()).to_bytes(&mut buf[0..2]); + buf[2..128].copy_from_slice(&self.__pad.borrow()); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + ss_family: Rc::new(RefCell::new(::from_bytes(&buf[0..2]))), + __pad: Rc::new(RefCell::new(buf[2..128].to_vec().into_boxed_slice())), + } + } +} + +impl sockaddr_in { + pub fn to_libc(&self) -> ::libc::sockaddr_in { + let mut sin_zero = [0u8; 8]; + sin_zero.copy_from_slice(&self.sin_zero.borrow()); + ::libc::sockaddr_in { + sin_family: *self.sin_family.borrow(), + sin_port: *self.sin_port.borrow(), + sin_addr: ::libc::in_addr { + s_addr: *self.sin_addr.borrow().s_addr.borrow(), + }, + sin_zero, + } + } + pub fn from_libc(l: &::libc::sockaddr_in) -> Self { + Self { + sin_family: Rc::new(RefCell::new(l.sin_family)), + sin_port: Rc::new(RefCell::new(l.sin_port)), + sin_addr: Rc::new(RefCell::new(in_addr { + s_addr: Rc::new(RefCell::new(l.sin_addr.s_addr)), + })), + sin_zero: Rc::new(RefCell::new(l.sin_zero.to_vec().into_boxed_slice())), + } + } +} + +impl sockaddr_in6 { + pub fn to_libc(&self) -> ::libc::sockaddr_in6 { + let mut s6 = [0u8; 16]; + s6.copy_from_slice(&self.sin6_addr.borrow().s6_addr.borrow()); + ::libc::sockaddr_in6 { + sin6_family: *self.sin6_family.borrow(), + sin6_port: *self.sin6_port.borrow(), + sin6_flowinfo: *self.sin6_flowinfo.borrow(), + sin6_addr: ::libc::in6_addr { s6_addr: s6 }, + sin6_scope_id: *self.sin6_scope_id.borrow(), + } + } + pub fn from_libc(l: &::libc::sockaddr_in6) -> Self { + Self { + sin6_family: Rc::new(RefCell::new(l.sin6_family)), + sin6_port: Rc::new(RefCell::new(l.sin6_port)), + sin6_flowinfo: Rc::new(RefCell::new(l.sin6_flowinfo)), + sin6_addr: Rc::new(RefCell::new(in6_addr { + s6_addr: Rc::new(RefCell::new( + l.sin6_addr.s6_addr.to_vec().into_boxed_slice(), + )), + })), + sin6_scope_id: Rc::new(RefCell::new(l.sin6_scope_id)), + } + } +} + +pub fn decode_sockaddr( + addr: &Ptr, + _len: u32, +) -> Option> { + let family = addr.reinterpret_cast::().read(); + if family == ::libc::AF_INET as u16 { + let m = addr.reinterpret_cast::().read(); + Some(Box::new(nix::sys::socket::SockaddrIn::from(m.to_libc()))) + } else if family == ::libc::AF_INET6 as u16 { + let m = addr.reinterpret_cast::().read(); + Some(Box::new(nix::sys::socket::SockaddrIn6::from(m.to_libc()))) + } else if family == ::libc::AF_UNIX as u16 { + let m = addr.reinterpret_cast::().read(); + let path = m.sun_path.borrow(); + let end = path.iter().position(|&c| c == 0).unwrap_or(path.len()); + let bytes: Vec = path[..end].to_vec(); + nix::sys::socket::UnixAddr::new(&bytes[..]) + .ok() + .map(|u| Box::new(u) as Box) + } else { + None + } +} + +pub fn encode_sockaddr( + ss: &nix::sys::socket::SockaddrStorage, + out: &Ptr, + out_len: &Ptr, +) { + use nix::sys::socket::{AddressFamily, SockaddrLike}; + match ss.family() { + Some(AddressFamily::Inet) => { + let l = ::libc::sockaddr_in::from(*ss.as_sockaddr_in().unwrap()); + out.reinterpret_cast::() + .write(sockaddr_in::from_libc(&l)); + } + Some(AddressFamily::Inet6) => { + let l = ::libc::sockaddr_in6::from(*ss.as_sockaddr_in6().unwrap()); + out.reinterpret_cast::() + .write(sockaddr_in6::from_libc(&l)); + } + _ => {} + } + out_len.write(ss.len()); +} + +impl ByteRepr for ::libc::sockaddr {} +impl ByteRepr for ::libc::sockaddr_in {} +impl ByteRepr for ::libc::sockaddr_in6 {} +impl ByteRepr for ::libc::sockaddr_un {} +impl ByteRepr for ::libc::sockaddr_storage {} diff --git a/libcc2rs/src/libc_shims/stat.rs b/libcc2rs/src/libc_shims/stat.rs new file mode 100644 index 00000000..22a9b7ae --- /dev/null +++ b/libcc2rs/src/libc_shims/stat.rs @@ -0,0 +1,86 @@ +// Copyright (c) 2022-present INESC-ID. +// Distributed under the MIT license that can be found in the LICENSE file. + +use crate::{ByteRepr, Value}; +use std::cell::RefCell; +use std::rc::Rc; + +pub struct stat { + pub st_dev: Value, + pub st_ino: Value, + pub st_nlink: Value, + pub st_mode: Value, + pub st_uid: Value, + pub st_gid: Value, + pub st_rdev: Value, + pub st_size: Value, + pub st_blksize: Value, + pub st_blocks: Value, + pub st_atime: Value, + pub st_mtime: Value, + pub st_ctime: Value, +} + +impl Default for stat { + fn default() -> Self { + Self { + st_dev: Rc::new(RefCell::new(0)), + st_ino: Rc::new(RefCell::new(0)), + st_nlink: Rc::new(RefCell::new(0)), + st_mode: Rc::new(RefCell::new(0)), + st_uid: Rc::new(RefCell::new(0)), + st_gid: Rc::new(RefCell::new(0)), + st_rdev: Rc::new(RefCell::new(0)), + st_size: Rc::new(RefCell::new(0)), + st_blksize: Rc::new(RefCell::new(0)), + st_blocks: Rc::new(RefCell::new(0)), + st_atime: Rc::new(RefCell::new(0)), + st_mtime: Rc::new(RefCell::new(0)), + st_ctime: Rc::new(RefCell::new(0)), + } + } +} + +impl Clone for stat { + fn clone(&self) -> Self { + Self { + st_dev: Rc::new(RefCell::new(*self.st_dev.borrow())), + st_ino: Rc::new(RefCell::new(*self.st_ino.borrow())), + st_nlink: Rc::new(RefCell::new(*self.st_nlink.borrow())), + st_mode: Rc::new(RefCell::new(*self.st_mode.borrow())), + st_uid: Rc::new(RefCell::new(*self.st_uid.borrow())), + st_gid: Rc::new(RefCell::new(*self.st_gid.borrow())), + st_rdev: Rc::new(RefCell::new(*self.st_rdev.borrow())), + st_size: Rc::new(RefCell::new(*self.st_size.borrow())), + st_blksize: Rc::new(RefCell::new(*self.st_blksize.borrow())), + st_blocks: Rc::new(RefCell::new(*self.st_blocks.borrow())), + st_atime: Rc::new(RefCell::new(*self.st_atime.borrow())), + st_mtime: Rc::new(RefCell::new(*self.st_mtime.borrow())), + st_ctime: Rc::new(RefCell::new(*self.st_ctime.borrow())), + } + } +} + +impl ByteRepr for stat {} + +impl stat { + pub fn from_libc(l: &::libc::stat) -> Self { + Self { + st_dev: Rc::new(RefCell::new(l.st_dev)), + st_ino: Rc::new(RefCell::new(l.st_ino)), + st_nlink: Rc::new(RefCell::new(l.st_nlink)), + st_mode: Rc::new(RefCell::new(l.st_mode)), + st_uid: Rc::new(RefCell::new(l.st_uid)), + st_gid: Rc::new(RefCell::new(l.st_gid)), + st_rdev: Rc::new(RefCell::new(l.st_rdev)), + st_size: Rc::new(RefCell::new(l.st_size)), + st_blksize: Rc::new(RefCell::new(l.st_blksize)), + st_blocks: Rc::new(RefCell::new(l.st_blocks)), + st_atime: Rc::new(RefCell::new(l.st_atime)), + st_mtime: Rc::new(RefCell::new(l.st_mtime)), + st_ctime: Rc::new(RefCell::new(l.st_ctime)), + } + } +} + +impl ByteRepr for ::libc::stat {} diff --git a/libcc2rs/src/libc_shims/termios.rs b/libcc2rs/src/libc_shims/termios.rs new file mode 100644 index 00000000..00e0b60f --- /dev/null +++ b/libcc2rs/src/libc_shims/termios.rs @@ -0,0 +1,80 @@ +// Copyright (c) 2022-present INESC-ID. +// Distributed under the MIT license that can be found in the LICENSE file. + +use crate::{ByteRepr, Value}; +use std::cell::RefCell; +use std::rc::Rc; + +pub struct termios { + pub c_iflag: Value, + pub c_oflag: Value, + pub c_cflag: Value, + pub c_lflag: Value, + pub c_line: Value, + pub c_cc: Value>, + pub c_ispeed: Value, + pub c_ospeed: Value, +} + +impl Default for termios { + fn default() -> Self { + Self { + c_iflag: Rc::new(RefCell::new(0)), + c_oflag: Rc::new(RefCell::new(0)), + c_cflag: Rc::new(RefCell::new(0)), + c_lflag: Rc::new(RefCell::new(0)), + c_line: Rc::new(RefCell::new(0)), + c_cc: Rc::new(RefCell::new(vec![0u8; 32].into_boxed_slice())), + c_ispeed: Rc::new(RefCell::new(0)), + c_ospeed: Rc::new(RefCell::new(0)), + } + } +} + +impl Clone for termios { + fn clone(&self) -> Self { + Self { + c_iflag: Rc::new(RefCell::new(*self.c_iflag.borrow())), + c_oflag: Rc::new(RefCell::new(*self.c_oflag.borrow())), + c_cflag: Rc::new(RefCell::new(*self.c_cflag.borrow())), + c_lflag: Rc::new(RefCell::new(*self.c_lflag.borrow())), + c_line: Rc::new(RefCell::new(*self.c_line.borrow())), + c_cc: Rc::new(RefCell::new(self.c_cc.borrow().clone())), + c_ispeed: Rc::new(RefCell::new(*self.c_ispeed.borrow())), + c_ospeed: Rc::new(RefCell::new(*self.c_ospeed.borrow())), + } + } +} + +impl ByteRepr for termios {} + +pub struct winsize { + pub ws_row: Value, + pub ws_col: Value, + pub ws_xpixel: Value, + pub ws_ypixel: Value, +} + +impl Default for winsize { + fn default() -> Self { + Self { + ws_row: Rc::new(RefCell::new(0)), + ws_col: Rc::new(RefCell::new(0)), + ws_xpixel: Rc::new(RefCell::new(0)), + ws_ypixel: Rc::new(RefCell::new(0)), + } + } +} + +impl Clone for winsize { + fn clone(&self) -> Self { + Self { + ws_row: Rc::new(RefCell::new(*self.ws_row.borrow())), + ws_col: Rc::new(RefCell::new(*self.ws_col.borrow())), + ws_xpixel: Rc::new(RefCell::new(*self.ws_xpixel.borrow())), + ws_ypixel: Rc::new(RefCell::new(*self.ws_ypixel.borrow())), + } + } +} + +impl ByteRepr for winsize {} diff --git a/libcc2rs/src/libc_shims/time.rs b/libcc2rs/src/libc_shims/time.rs new file mode 100644 index 00000000..ce5aaa7c --- /dev/null +++ b/libcc2rs/src/libc_shims/time.rs @@ -0,0 +1,112 @@ +// Copyright (c) 2022-present INESC-ID. +// Distributed under the MIT license that can be found in the LICENSE file. + +use crate::{ByteRepr, Ptr, Value}; +use std::cell::RefCell; +use std::rc::Rc; + +pub struct tm { + pub tm_sec: Value, + pub tm_min: Value, + pub tm_hour: Value, + pub tm_mday: Value, + pub tm_mon: Value, + pub tm_year: Value, + pub tm_wday: Value, + pub tm_yday: Value, + pub tm_isdst: Value, + pub tm_gmtoff: Value, + pub tm_zone: Value>, +} + +impl Default for tm { + fn default() -> Self { + Self { + tm_sec: Rc::new(RefCell::new(0)), + tm_min: Rc::new(RefCell::new(0)), + tm_hour: Rc::new(RefCell::new(0)), + tm_mday: Rc::new(RefCell::new(0)), + tm_mon: Rc::new(RefCell::new(0)), + tm_year: Rc::new(RefCell::new(0)), + tm_wday: Rc::new(RefCell::new(0)), + tm_yday: Rc::new(RefCell::new(0)), + tm_isdst: Rc::new(RefCell::new(0)), + tm_gmtoff: Rc::new(RefCell::new(0)), + tm_zone: Rc::new(RefCell::new(Ptr::null())), + } + } +} + +impl Clone for tm { + fn clone(&self) -> Self { + Self { + tm_sec: Rc::new(RefCell::new(*self.tm_sec.borrow())), + tm_min: Rc::new(RefCell::new(*self.tm_min.borrow())), + tm_hour: Rc::new(RefCell::new(*self.tm_hour.borrow())), + tm_mday: Rc::new(RefCell::new(*self.tm_mday.borrow())), + tm_mon: Rc::new(RefCell::new(*self.tm_mon.borrow())), + tm_year: Rc::new(RefCell::new(*self.tm_year.borrow())), + tm_wday: Rc::new(RefCell::new(*self.tm_wday.borrow())), + tm_yday: Rc::new(RefCell::new(*self.tm_yday.borrow())), + tm_isdst: Rc::new(RefCell::new(*self.tm_isdst.borrow())), + tm_gmtoff: Rc::new(RefCell::new(*self.tm_gmtoff.borrow())), + tm_zone: Rc::new(RefCell::new(self.tm_zone.borrow().clone())), + } + } +} + +impl ByteRepr for tm {} + +pub struct timeval { + pub tv_sec: Value, + pub tv_usec: Value, +} + +impl Default for timeval { + fn default() -> Self { + Self { + tv_sec: Rc::new(RefCell::new(0)), + tv_usec: Rc::new(RefCell::new(0)), + } + } +} + +impl Clone for timeval { + fn clone(&self) -> Self { + Self { + tv_sec: Rc::new(RefCell::new(*self.tv_sec.borrow())), + tv_usec: Rc::new(RefCell::new(*self.tv_usec.borrow())), + } + } +} + +impl ByteRepr for timeval {} + +pub struct timespec { + pub tv_sec: Value, + pub tv_nsec: Value, +} + +impl Default for timespec { + fn default() -> Self { + Self { + tv_sec: Rc::new(RefCell::new(0)), + tv_nsec: Rc::new(RefCell::new(0)), + } + } +} + +impl Clone for timespec { + fn clone(&self) -> Self { + Self { + tv_sec: Rc::new(RefCell::new(*self.tv_sec.borrow())), + tv_nsec: Rc::new(RefCell::new(*self.tv_nsec.borrow())), + } + } +} + +impl ByteRepr for timespec {} + +impl ByteRepr for ::libc::tm {} +impl ByteRepr for ::libc::timeval {} +impl ByteRepr for ::libc::timespec {} From 229d0987cea8a6d1692d5a2974bcb6685872c37d Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Wed, 15 Jul 2026 10:12:50 +0100 Subject: [PATCH 5/8] Plug libc_shim in lib.rs --- libcc2rs/src/lib.rs | 3 + libcc2rs/src/libc_shims/dirent.rs | 8 +- libcc2rs/src/libc_shims/ifaddrs.rs | 16 +-- libcc2rs/src/libc_shims/ip.rs | 16 +-- libcc2rs/src/libc_shims/mod.rs | 2 - libcc2rs/src/libc_shims/netdb.rs | 14 +-- libcc2rs/src/libc_shims/poll.rs | 8 +- libcc2rs/src/libc_shims/pwd.rs | 8 +- libcc2rs/src/libc_shims/socket.rs | 110 +++++------------- libcc2rs/src/libc_shims/stat.rs | 10 +- libcc2rs/src/libc_shims/termios.rs | 16 +-- libcc2rs/src/libc_shims/time.rs | 24 ++-- rules/dirent/tgt_refcount.rs | 12 ++ rules/ifaddrs/tgt_refcount.rs | 8 ++ rules/ip/tgt_refcount.rs | 20 ++++ rules/netdb/tgt_refcount.rs | 8 ++ rules/poll/tgt_refcount.rs | 8 ++ rules/pwd/tgt_refcount.rs | 8 ++ rules/socket/tgt_refcount.rs | 16 +++ rules/src/modules.rs | 20 ++++ rules/stat/tgt_refcount.rs | 8 ++ rules/termios/tgt_refcount.rs | 12 ++ rules/time/tgt_refcount.rs | 16 +++ tests/unit/libc_struct_without_default.cpp | 1 - .../refcount/libc_struct_without_default.rs | 89 ++++++++++++++ 25 files changed, 320 insertions(+), 141 deletions(-) create mode 100644 rules/dirent/tgt_refcount.rs create mode 100644 rules/ifaddrs/tgt_refcount.rs create mode 100644 rules/ip/tgt_refcount.rs create mode 100644 rules/netdb/tgt_refcount.rs create mode 100644 rules/poll/tgt_refcount.rs create mode 100644 rules/pwd/tgt_refcount.rs create mode 100644 rules/socket/tgt_refcount.rs create mode 100644 rules/stat/tgt_refcount.rs create mode 100644 rules/termios/tgt_refcount.rs create mode 100644 rules/time/tgt_refcount.rs create mode 100644 tests/unit/out/refcount/libc_struct_without_default.rs diff --git a/libcc2rs/src/lib.rs b/libcc2rs/src/lib.rs index 4288464f..e9046a7f 100644 --- a/libcc2rs/src/lib.rs +++ b/libcc2rs/src/lib.rs @@ -7,6 +7,9 @@ pub use reinterpret::ByteRepr; mod rc; pub use rc::*; +mod libc_shims; +pub use libc_shims::*; + mod fn_ptr; pub use fn_ptr::FnPtr; diff --git a/libcc2rs/src/libc_shims/dirent.rs b/libcc2rs/src/libc_shims/dirent.rs index bfdb0a4e..8ef3d3ae 100644 --- a/libcc2rs/src/libc_shims/dirent.rs +++ b/libcc2rs/src/libc_shims/dirent.rs @@ -5,7 +5,7 @@ use crate::{ByteRepr, Value}; use std::cell::RefCell; use std::rc::Rc; -pub struct dirent { +pub struct Dirent { pub d_ino: Value, pub d_off: Value, pub d_reclen: Value, @@ -13,7 +13,7 @@ pub struct dirent { pub d_name: Value>, } -impl Default for dirent { +impl Default for Dirent { fn default() -> Self { Self { d_ino: Rc::new(RefCell::new(0)), @@ -25,7 +25,7 @@ impl Default for dirent { } } -impl Clone for dirent { +impl Clone for Dirent { fn clone(&self) -> Self { Self { d_ino: Rc::new(RefCell::new(*self.d_ino.borrow())), @@ -37,7 +37,7 @@ impl Clone for dirent { } } -impl ByteRepr for dirent {} +impl ByteRepr for Dirent {} pub struct CDir { pub entries: Vec<(u64, Vec, u8)>, diff --git a/libcc2rs/src/libc_shims/ifaddrs.rs b/libcc2rs/src/libc_shims/ifaddrs.rs index e6e4cf3f..a1bde73a 100644 --- a/libcc2rs/src/libc_shims/ifaddrs.rs +++ b/libcc2rs/src/libc_shims/ifaddrs.rs @@ -1,20 +1,20 @@ // Copyright (c) 2022-present INESC-ID. // Distributed under the MIT license that can be found in the LICENSE file. -use super::sockaddr; +use super::Sockaddr; use crate::{ByteRepr, Ptr, Value}; use std::cell::RefCell; use std::rc::Rc; -pub struct ifaddrs { - pub ifa_next: Value>, +pub struct Ifaddrs { + pub ifa_next: Value>, pub ifa_name: Value>, pub ifa_flags: Value, - pub ifa_addr: Value>, - pub ifa_netmask: Value>, + pub ifa_addr: Value>, + pub ifa_netmask: Value>, } -impl Default for ifaddrs { +impl Default for Ifaddrs { fn default() -> Self { Self { ifa_next: Rc::new(RefCell::new(Ptr::null())), @@ -26,7 +26,7 @@ impl Default for ifaddrs { } } -impl Clone for ifaddrs { +impl Clone for Ifaddrs { fn clone(&self) -> Self { Self { ifa_next: Rc::new(RefCell::new(self.ifa_next.borrow().clone())), @@ -38,6 +38,6 @@ impl Clone for ifaddrs { } } -impl ByteRepr for ifaddrs {} +impl ByteRepr for Ifaddrs {} impl ByteRepr for ::libc::ifaddrs {} diff --git a/libcc2rs/src/libc_shims/ip.rs b/libcc2rs/src/libc_shims/ip.rs index 1d6b45e7..e767de54 100644 --- a/libcc2rs/src/libc_shims/ip.rs +++ b/libcc2rs/src/libc_shims/ip.rs @@ -6,21 +6,21 @@ use std::cell::RefCell; use std::rc::Rc; #[derive(Default)] -pub struct in_addr { +pub struct InAddr { pub s_addr: Value, } -pub struct in6_addr { +pub struct In6Addr { pub s6_addr: Value>, } -impl in6_addr { +impl In6Addr { pub fn s6_addr(&self) -> Ptr { self.s6_addr.as_pointer() } } -impl Default for in6_addr { +impl Default for In6Addr { fn default() -> Self { Self { s6_addr: Rc::new(RefCell::new(vec![0u8; 16].into_boxed_slice())), @@ -28,7 +28,7 @@ impl Default for in6_addr { } } -impl Clone for in_addr { +impl Clone for InAddr { fn clone(&self) -> Self { Self { s_addr: Rc::new(RefCell::new(*self.s_addr.borrow())), @@ -36,7 +36,7 @@ impl Clone for in_addr { } } -impl Clone for in6_addr { +impl Clone for In6Addr { fn clone(&self) -> Self { Self { s6_addr: Rc::new(RefCell::new(self.s6_addr.borrow().clone())), @@ -44,7 +44,7 @@ impl Clone for in6_addr { } } -impl ByteRepr for in_addr { +impl ByteRepr for InAddr { fn byte_size() -> usize { 4 } @@ -58,7 +58,7 @@ impl ByteRepr for in_addr { } } -impl ByteRepr for in6_addr { +impl ByteRepr for In6Addr { fn byte_size() -> usize { 16 } diff --git a/libcc2rs/src/libc_shims/mod.rs b/libcc2rs/src/libc_shims/mod.rs index 1ef02870..9388e478 100644 --- a/libcc2rs/src/libc_shims/mod.rs +++ b/libcc2rs/src/libc_shims/mod.rs @@ -1,8 +1,6 @@ // Copyright (c) 2022-present INESC-ID. // Distributed under the MIT license that can be found in the LICENSE file. -#![allow(non_camel_case_types)] - mod dirent; mod ifaddrs; mod ip; diff --git a/libcc2rs/src/libc_shims/netdb.rs b/libcc2rs/src/libc_shims/netdb.rs index efbaf5be..a3ef5015 100644 --- a/libcc2rs/src/libc_shims/netdb.rs +++ b/libcc2rs/src/libc_shims/netdb.rs @@ -1,23 +1,23 @@ // Copyright (c) 2022-present INESC-ID. // Distributed under the MIT license that can be found in the LICENSE file. -use super::sockaddr; +use super::Sockaddr; use crate::{ByteRepr, Ptr, Value}; use std::cell::RefCell; use std::rc::Rc; -pub struct addrinfo { +pub struct Addrinfo { pub ai_flags: Value, pub ai_family: Value, pub ai_socktype: Value, pub ai_protocol: Value, pub ai_addrlen: Value, - pub ai_addr: Value>, + pub ai_addr: Value>, pub ai_canonname: Value>, - pub ai_next: Value>, + pub ai_next: Value>, } -impl Default for addrinfo { +impl Default for Addrinfo { fn default() -> Self { Self { ai_flags: Rc::new(RefCell::new(0)), @@ -32,7 +32,7 @@ impl Default for addrinfo { } } -impl Clone for addrinfo { +impl Clone for Addrinfo { fn clone(&self) -> Self { Self { ai_flags: Rc::new(RefCell::new(*self.ai_flags.borrow())), @@ -47,6 +47,6 @@ impl Clone for addrinfo { } } -impl ByteRepr for addrinfo {} +impl ByteRepr for Addrinfo {} impl ByteRepr for ::libc::addrinfo {} diff --git a/libcc2rs/src/libc_shims/poll.rs b/libcc2rs/src/libc_shims/poll.rs index 9e782ff3..1634d395 100644 --- a/libcc2rs/src/libc_shims/poll.rs +++ b/libcc2rs/src/libc_shims/poll.rs @@ -5,13 +5,13 @@ use crate::{ByteRepr, Value}; use std::cell::RefCell; use std::rc::Rc; -pub struct pollfd { +pub struct Pollfd { pub fd: Value, pub events: Value, pub revents: Value, } -impl Default for pollfd { +impl Default for Pollfd { fn default() -> Self { Self { fd: Rc::new(RefCell::new(0)), @@ -21,7 +21,7 @@ impl Default for pollfd { } } -impl Clone for pollfd { +impl Clone for Pollfd { fn clone(&self) -> Self { Self { fd: Rc::new(RefCell::new(*self.fd.borrow())), @@ -31,6 +31,6 @@ impl Clone for pollfd { } } -impl ByteRepr for pollfd {} +impl ByteRepr for Pollfd {} impl ByteRepr for ::libc::pollfd {} diff --git a/libcc2rs/src/libc_shims/pwd.rs b/libcc2rs/src/libc_shims/pwd.rs index 9156eb7e..d50fb9fe 100644 --- a/libcc2rs/src/libc_shims/pwd.rs +++ b/libcc2rs/src/libc_shims/pwd.rs @@ -5,7 +5,7 @@ use crate::{ByteRepr, Ptr, Value}; use std::cell::RefCell; use std::rc::Rc; -pub struct passwd { +pub struct Passwd { pub pw_name: Value>, pub pw_passwd: Value>, pub pw_uid: Value, @@ -15,7 +15,7 @@ pub struct passwd { pub pw_shell: Value>, } -impl Default for passwd { +impl Default for Passwd { fn default() -> Self { Self { pw_name: Rc::new(RefCell::new(Ptr::null())), @@ -29,7 +29,7 @@ impl Default for passwd { } } -impl Clone for passwd { +impl Clone for Passwd { fn clone(&self) -> Self { Self { pw_name: Rc::new(RefCell::new(self.pw_name.borrow().clone())), @@ -43,6 +43,6 @@ impl Clone for passwd { } } -impl ByteRepr for passwd {} +impl ByteRepr for Passwd {} impl ByteRepr for ::libc::passwd {} diff --git a/libcc2rs/src/libc_shims/socket.rs b/libcc2rs/src/libc_shims/socket.rs index 4521c6c9..1e815a35 100644 --- a/libcc2rs/src/libc_shims/socket.rs +++ b/libcc2rs/src/libc_shims/socket.rs @@ -1,42 +1,42 @@ // Copyright (c) 2022-present INESC-ID. // Distributed under the MIT license that can be found in the LICENSE file. -use super::{in6_addr, in_addr}; -use crate::{ByteRepr, Ptr, Value}; +use super::{In6Addr, InAddr}; +use crate::{ByteRepr, Value}; use std::cell::RefCell; use std::rc::Rc; -pub struct sockaddr { +pub struct Sockaddr { pub sa_family: Value, pub sa_data: Value>, } -pub struct sockaddr_in { +pub struct SockaddrIn { pub sin_family: Value, pub sin_port: Value, - pub sin_addr: Value, + pub sin_addr: Value, pub sin_zero: Value>, } -pub struct sockaddr_in6 { +pub struct SockaddrIn6 { pub sin6_family: Value, pub sin6_port: Value, pub sin6_flowinfo: Value, - pub sin6_addr: Value, + pub sin6_addr: Value, pub sin6_scope_id: Value, } -pub struct sockaddr_un { +pub struct SockaddrUn { pub sun_family: Value, pub sun_path: Value>, } -pub struct sockaddr_storage { +pub struct SockaddrStorage { pub ss_family: Value, pub __pad: Value>, } -impl Default for sockaddr { +impl Default for Sockaddr { fn default() -> Self { Self { sa_family: Rc::new(RefCell::new(0)), @@ -45,30 +45,30 @@ impl Default for sockaddr { } } -impl Default for sockaddr_in { +impl Default for SockaddrIn { fn default() -> Self { Self { sin_family: Rc::new(RefCell::new(0)), sin_port: Rc::new(RefCell::new(0)), - sin_addr: Rc::new(RefCell::new(in_addr::default())), + sin_addr: Rc::new(RefCell::new(InAddr::default())), sin_zero: Rc::new(RefCell::new(vec![0u8; 8].into_boxed_slice())), } } } -impl Default for sockaddr_in6 { +impl Default for SockaddrIn6 { fn default() -> Self { Self { sin6_family: Rc::new(RefCell::new(0)), sin6_port: Rc::new(RefCell::new(0)), sin6_flowinfo: Rc::new(RefCell::new(0)), - sin6_addr: Rc::new(RefCell::new(in6_addr::default())), + sin6_addr: Rc::new(RefCell::new(In6Addr::default())), sin6_scope_id: Rc::new(RefCell::new(0)), } } } -impl Default for sockaddr_un { +impl Default for SockaddrUn { fn default() -> Self { Self { sun_family: Rc::new(RefCell::new(0)), @@ -77,7 +77,7 @@ impl Default for sockaddr_un { } } -impl Default for sockaddr_storage { +impl Default for SockaddrStorage { fn default() -> Self { Self { ss_family: Rc::new(RefCell::new(0)), @@ -86,7 +86,7 @@ impl Default for sockaddr_storage { } } -impl Clone for sockaddr { +impl Clone for Sockaddr { fn clone(&self) -> Self { Self { sa_family: Rc::new(RefCell::new(*self.sa_family.borrow())), @@ -95,7 +95,7 @@ impl Clone for sockaddr { } } -impl Clone for sockaddr_in { +impl Clone for SockaddrIn { fn clone(&self) -> Self { Self { sin_family: Rc::new(RefCell::new(*self.sin_family.borrow())), @@ -106,7 +106,7 @@ impl Clone for sockaddr_in { } } -impl Clone for sockaddr_in6 { +impl Clone for SockaddrIn6 { fn clone(&self) -> Self { Self { sin6_family: Rc::new(RefCell::new(*self.sin6_family.borrow())), @@ -118,7 +118,7 @@ impl Clone for sockaddr_in6 { } } -impl Clone for sockaddr_un { +impl Clone for SockaddrUn { fn clone(&self) -> Self { Self { sun_family: Rc::new(RefCell::new(*self.sun_family.borrow())), @@ -127,7 +127,7 @@ impl Clone for sockaddr_un { } } -impl Clone for sockaddr_storage { +impl Clone for SockaddrStorage { fn clone(&self) -> Self { Self { ss_family: Rc::new(RefCell::new(*self.ss_family.borrow())), @@ -136,7 +136,7 @@ impl Clone for sockaddr_storage { } } -impl ByteRepr for sockaddr { +impl ByteRepr for Sockaddr { fn byte_size() -> usize { 16 } @@ -152,7 +152,7 @@ impl ByteRepr for sockaddr { } } -impl ByteRepr for sockaddr_in { +impl ByteRepr for SockaddrIn { fn byte_size() -> usize { 16 } @@ -166,13 +166,13 @@ impl ByteRepr for sockaddr_in { Self { sin_family: Rc::new(RefCell::new(::from_bytes(&buf[0..2]))), sin_port: Rc::new(RefCell::new(::from_bytes(&buf[2..4]))), - sin_addr: Rc::new(RefCell::new(::from_bytes(&buf[4..8]))), + sin_addr: Rc::new(RefCell::new(::from_bytes(&buf[4..8]))), sin_zero: Rc::new(RefCell::new(buf[8..16].to_vec().into_boxed_slice())), } } } -impl ByteRepr for sockaddr_in6 { +impl ByteRepr for SockaddrIn6 { fn byte_size() -> usize { 28 } @@ -188,13 +188,13 @@ impl ByteRepr for sockaddr_in6 { sin6_family: Rc::new(RefCell::new(::from_bytes(&buf[0..2]))), sin6_port: Rc::new(RefCell::new(::from_bytes(&buf[2..4]))), sin6_flowinfo: Rc::new(RefCell::new(::from_bytes(&buf[4..8]))), - sin6_addr: Rc::new(RefCell::new(::from_bytes(&buf[8..24]))), + sin6_addr: Rc::new(RefCell::new(::from_bytes(&buf[8..24]))), sin6_scope_id: Rc::new(RefCell::new(::from_bytes(&buf[24..28]))), } } } -impl ByteRepr for sockaddr_un { +impl ByteRepr for SockaddrUn { fn byte_size() -> usize { 110 } @@ -210,7 +210,7 @@ impl ByteRepr for sockaddr_un { } } -impl ByteRepr for sockaddr_storage { +impl ByteRepr for SockaddrStorage { fn byte_size() -> usize { 128 } @@ -226,7 +226,7 @@ impl ByteRepr for sockaddr_storage { } } -impl sockaddr_in { +impl SockaddrIn { pub fn to_libc(&self) -> ::libc::sockaddr_in { let mut sin_zero = [0u8; 8]; sin_zero.copy_from_slice(&self.sin_zero.borrow()); @@ -243,7 +243,7 @@ impl sockaddr_in { Self { sin_family: Rc::new(RefCell::new(l.sin_family)), sin_port: Rc::new(RefCell::new(l.sin_port)), - sin_addr: Rc::new(RefCell::new(in_addr { + sin_addr: Rc::new(RefCell::new(InAddr { s_addr: Rc::new(RefCell::new(l.sin_addr.s_addr)), })), sin_zero: Rc::new(RefCell::new(l.sin_zero.to_vec().into_boxed_slice())), @@ -251,7 +251,7 @@ impl sockaddr_in { } } -impl sockaddr_in6 { +impl SockaddrIn6 { pub fn to_libc(&self) -> ::libc::sockaddr_in6 { let mut s6 = [0u8; 16]; s6.copy_from_slice(&self.sin6_addr.borrow().s6_addr.borrow()); @@ -268,7 +268,7 @@ impl sockaddr_in6 { sin6_family: Rc::new(RefCell::new(l.sin6_family)), sin6_port: Rc::new(RefCell::new(l.sin6_port)), sin6_flowinfo: Rc::new(RefCell::new(l.sin6_flowinfo)), - sin6_addr: Rc::new(RefCell::new(in6_addr { + sin6_addr: Rc::new(RefCell::new(In6Addr { s6_addr: Rc::new(RefCell::new( l.sin6_addr.s6_addr.to_vec().into_boxed_slice(), )), @@ -278,52 +278,6 @@ impl sockaddr_in6 { } } -pub fn decode_sockaddr( - addr: &Ptr, - _len: u32, -) -> Option> { - let family = addr.reinterpret_cast::().read(); - if family == ::libc::AF_INET as u16 { - let m = addr.reinterpret_cast::().read(); - Some(Box::new(nix::sys::socket::SockaddrIn::from(m.to_libc()))) - } else if family == ::libc::AF_INET6 as u16 { - let m = addr.reinterpret_cast::().read(); - Some(Box::new(nix::sys::socket::SockaddrIn6::from(m.to_libc()))) - } else if family == ::libc::AF_UNIX as u16 { - let m = addr.reinterpret_cast::().read(); - let path = m.sun_path.borrow(); - let end = path.iter().position(|&c| c == 0).unwrap_or(path.len()); - let bytes: Vec = path[..end].to_vec(); - nix::sys::socket::UnixAddr::new(&bytes[..]) - .ok() - .map(|u| Box::new(u) as Box) - } else { - None - } -} - -pub fn encode_sockaddr( - ss: &nix::sys::socket::SockaddrStorage, - out: &Ptr, - out_len: &Ptr, -) { - use nix::sys::socket::{AddressFamily, SockaddrLike}; - match ss.family() { - Some(AddressFamily::Inet) => { - let l = ::libc::sockaddr_in::from(*ss.as_sockaddr_in().unwrap()); - out.reinterpret_cast::() - .write(sockaddr_in::from_libc(&l)); - } - Some(AddressFamily::Inet6) => { - let l = ::libc::sockaddr_in6::from(*ss.as_sockaddr_in6().unwrap()); - out.reinterpret_cast::() - .write(sockaddr_in6::from_libc(&l)); - } - _ => {} - } - out_len.write(ss.len()); -} - impl ByteRepr for ::libc::sockaddr {} impl ByteRepr for ::libc::sockaddr_in {} impl ByteRepr for ::libc::sockaddr_in6 {} diff --git a/libcc2rs/src/libc_shims/stat.rs b/libcc2rs/src/libc_shims/stat.rs index 22a9b7ae..c98476b5 100644 --- a/libcc2rs/src/libc_shims/stat.rs +++ b/libcc2rs/src/libc_shims/stat.rs @@ -5,7 +5,7 @@ use crate::{ByteRepr, Value}; use std::cell::RefCell; use std::rc::Rc; -pub struct stat { +pub struct Stat { pub st_dev: Value, pub st_ino: Value, pub st_nlink: Value, @@ -21,7 +21,7 @@ pub struct stat { pub st_ctime: Value, } -impl Default for stat { +impl Default for Stat { fn default() -> Self { Self { st_dev: Rc::new(RefCell::new(0)), @@ -41,7 +41,7 @@ impl Default for stat { } } -impl Clone for stat { +impl Clone for Stat { fn clone(&self) -> Self { Self { st_dev: Rc::new(RefCell::new(*self.st_dev.borrow())), @@ -61,9 +61,9 @@ impl Clone for stat { } } -impl ByteRepr for stat {} +impl ByteRepr for Stat {} -impl stat { +impl Stat { pub fn from_libc(l: &::libc::stat) -> Self { Self { st_dev: Rc::new(RefCell::new(l.st_dev)), diff --git a/libcc2rs/src/libc_shims/termios.rs b/libcc2rs/src/libc_shims/termios.rs index 00e0b60f..8852e968 100644 --- a/libcc2rs/src/libc_shims/termios.rs +++ b/libcc2rs/src/libc_shims/termios.rs @@ -5,7 +5,7 @@ use crate::{ByteRepr, Value}; use std::cell::RefCell; use std::rc::Rc; -pub struct termios { +pub struct Termios { pub c_iflag: Value, pub c_oflag: Value, pub c_cflag: Value, @@ -16,7 +16,7 @@ pub struct termios { pub c_ospeed: Value, } -impl Default for termios { +impl Default for Termios { fn default() -> Self { Self { c_iflag: Rc::new(RefCell::new(0)), @@ -31,7 +31,7 @@ impl Default for termios { } } -impl Clone for termios { +impl Clone for Termios { fn clone(&self) -> Self { Self { c_iflag: Rc::new(RefCell::new(*self.c_iflag.borrow())), @@ -46,16 +46,16 @@ impl Clone for termios { } } -impl ByteRepr for termios {} +impl ByteRepr for Termios {} -pub struct winsize { +pub struct Winsize { pub ws_row: Value, pub ws_col: Value, pub ws_xpixel: Value, pub ws_ypixel: Value, } -impl Default for winsize { +impl Default for Winsize { fn default() -> Self { Self { ws_row: Rc::new(RefCell::new(0)), @@ -66,7 +66,7 @@ impl Default for winsize { } } -impl Clone for winsize { +impl Clone for Winsize { fn clone(&self) -> Self { Self { ws_row: Rc::new(RefCell::new(*self.ws_row.borrow())), @@ -77,4 +77,4 @@ impl Clone for winsize { } } -impl ByteRepr for winsize {} +impl ByteRepr for Winsize {} diff --git a/libcc2rs/src/libc_shims/time.rs b/libcc2rs/src/libc_shims/time.rs index ce5aaa7c..c581edfc 100644 --- a/libcc2rs/src/libc_shims/time.rs +++ b/libcc2rs/src/libc_shims/time.rs @@ -5,7 +5,7 @@ use crate::{ByteRepr, Ptr, Value}; use std::cell::RefCell; use std::rc::Rc; -pub struct tm { +pub struct Tm { pub tm_sec: Value, pub tm_min: Value, pub tm_hour: Value, @@ -19,7 +19,7 @@ pub struct tm { pub tm_zone: Value>, } -impl Default for tm { +impl Default for Tm { fn default() -> Self { Self { tm_sec: Rc::new(RefCell::new(0)), @@ -37,7 +37,7 @@ impl Default for tm { } } -impl Clone for tm { +impl Clone for Tm { fn clone(&self) -> Self { Self { tm_sec: Rc::new(RefCell::new(*self.tm_sec.borrow())), @@ -55,14 +55,14 @@ impl Clone for tm { } } -impl ByteRepr for tm {} +impl ByteRepr for Tm {} -pub struct timeval { +pub struct Timeval { pub tv_sec: Value, pub tv_usec: Value, } -impl Default for timeval { +impl Default for Timeval { fn default() -> Self { Self { tv_sec: Rc::new(RefCell::new(0)), @@ -71,7 +71,7 @@ impl Default for timeval { } } -impl Clone for timeval { +impl Clone for Timeval { fn clone(&self) -> Self { Self { tv_sec: Rc::new(RefCell::new(*self.tv_sec.borrow())), @@ -80,14 +80,14 @@ impl Clone for timeval { } } -impl ByteRepr for timeval {} +impl ByteRepr for Timeval {} -pub struct timespec { +pub struct Timespec { pub tv_sec: Value, pub tv_nsec: Value, } -impl Default for timespec { +impl Default for Timespec { fn default() -> Self { Self { tv_sec: Rc::new(RefCell::new(0)), @@ -96,7 +96,7 @@ impl Default for timespec { } } -impl Clone for timespec { +impl Clone for Timespec { fn clone(&self) -> Self { Self { tv_sec: Rc::new(RefCell::new(*self.tv_sec.borrow())), @@ -105,7 +105,7 @@ impl Clone for timespec { } } -impl ByteRepr for timespec {} +impl ByteRepr for Timespec {} impl ByteRepr for ::libc::tm {} impl ByteRepr for ::libc::timeval {} diff --git a/rules/dirent/tgt_refcount.rs b/rules/dirent/tgt_refcount.rs new file mode 100644 index 00000000..cb0b8f9b --- /dev/null +++ b/rules/dirent/tgt_refcount.rs @@ -0,0 +1,12 @@ +// Copyright (c) 2022-present INESC-ID. +// Distributed under the MIT license that can be found in the LICENSE file. + +use libcc2rs::*; + +fn t1() -> Ptr { + Ptr::null() +} + +fn t2() -> libcc2rs::Dirent { + Default::default() +} diff --git a/rules/ifaddrs/tgt_refcount.rs b/rules/ifaddrs/tgt_refcount.rs new file mode 100644 index 00000000..152bb0df --- /dev/null +++ b/rules/ifaddrs/tgt_refcount.rs @@ -0,0 +1,8 @@ +// Copyright (c) 2022-present INESC-ID. +// Distributed under the MIT license that can be found in the LICENSE file. + +use libcc2rs::*; + +fn t1() -> libcc2rs::Ifaddrs { + Default::default() +} diff --git a/rules/ip/tgt_refcount.rs b/rules/ip/tgt_refcount.rs new file mode 100644 index 00000000..93d61e13 --- /dev/null +++ b/rules/ip/tgt_refcount.rs @@ -0,0 +1,20 @@ +// Copyright (c) 2022-present INESC-ID. +// Distributed under the MIT license that can be found in the LICENSE file. + +use libcc2rs::*; + +fn t1() -> libcc2rs::SockaddrIn { + Default::default() +} + +fn t2() -> libcc2rs::InAddr { + Default::default() +} + +fn t3() -> libcc2rs::SockaddrIn6 { + Default::default() +} + +fn t4() -> libcc2rs::In6Addr { + Default::default() +} diff --git a/rules/netdb/tgt_refcount.rs b/rules/netdb/tgt_refcount.rs new file mode 100644 index 00000000..109eebf4 --- /dev/null +++ b/rules/netdb/tgt_refcount.rs @@ -0,0 +1,8 @@ +// Copyright (c) 2022-present INESC-ID. +// Distributed under the MIT license that can be found in the LICENSE file. + +use libcc2rs::*; + +fn t1() -> libcc2rs::Addrinfo { + Default::default() +} diff --git a/rules/poll/tgt_refcount.rs b/rules/poll/tgt_refcount.rs new file mode 100644 index 00000000..d8302a1e --- /dev/null +++ b/rules/poll/tgt_refcount.rs @@ -0,0 +1,8 @@ +// Copyright (c) 2022-present INESC-ID. +// Distributed under the MIT license that can be found in the LICENSE file. + +use libcc2rs::*; + +fn t1() -> libcc2rs::Pollfd { + Default::default() +} diff --git a/rules/pwd/tgt_refcount.rs b/rules/pwd/tgt_refcount.rs new file mode 100644 index 00000000..31c14099 --- /dev/null +++ b/rules/pwd/tgt_refcount.rs @@ -0,0 +1,8 @@ +// Copyright (c) 2022-present INESC-ID. +// Distributed under the MIT license that can be found in the LICENSE file. + +use libcc2rs::*; + +fn t1() -> libcc2rs::Passwd { + Default::default() +} diff --git a/rules/socket/tgt_refcount.rs b/rules/socket/tgt_refcount.rs new file mode 100644 index 00000000..8b1f7cd0 --- /dev/null +++ b/rules/socket/tgt_refcount.rs @@ -0,0 +1,16 @@ +// Copyright (c) 2022-present INESC-ID. +// Distributed under the MIT license that can be found in the LICENSE file. + +use libcc2rs::*; + +fn t1() -> libcc2rs::Sockaddr { + Default::default() +} + +fn t2() -> libcc2rs::SockaddrStorage { + Default::default() +} + +fn t3() -> libcc2rs::SockaddrUn { + Default::default() +} diff --git a/rules/src/modules.rs b/rules/src/modules.rs index e873ed19..e3cee97d 100644 --- a/rules/src/modules.rs +++ b/rules/src/modules.rs @@ -38,6 +38,8 @@ pub mod cstring_tgt_unsafe; pub mod deque_tgt_refcount; #[path = r#"../deque/tgt_unsafe.rs"#] pub mod deque_tgt_unsafe; +#[path = r#"../dirent/tgt_refcount.rs"#] +pub mod dirent_tgt_refcount; #[path = r#"../dirent/tgt_unsafe.rs"#] pub mod dirent_tgt_unsafe; #[path = r#"../errno/tgt_refcount.rs"#] @@ -56,6 +58,8 @@ pub mod fstream_tgt_unsafe; pub mod functional_tgt_refcount; #[path = r#"../functional/tgt_unsafe.rs"#] pub mod functional_tgt_unsafe; +#[path = r#"../ifaddrs/tgt_refcount.rs"#] +pub mod ifaddrs_tgt_refcount; #[path = r#"../ifaddrs/tgt_unsafe.rs"#] pub mod ifaddrs_tgt_unsafe; #[path = r#"../initializer_list/tgt_unsafe.rs"#] @@ -66,6 +70,8 @@ pub mod iomanip_tgt_unsafe; pub mod iostream_tgt_refcount; #[path = r#"../iostream/tgt_unsafe.rs"#] pub mod iostream_tgt_unsafe; +#[path = r#"../ip/tgt_refcount.rs"#] +pub mod ip_tgt_refcount; #[path = r#"../ip/tgt_unsafe.rs"#] pub mod ip_tgt_unsafe; #[path = r#"../limits/tgt_unsafe.rs"#] @@ -80,14 +86,20 @@ pub mod map_tgt_unsafe; pub mod math_tgt_unsafe; #[path = r#"../net_if/tgt_unsafe.rs"#] pub mod net_if_tgt_unsafe; +#[path = r#"../netdb/tgt_refcount.rs"#] +pub mod netdb_tgt_refcount; #[path = r#"../netdb/tgt_unsafe.rs"#] pub mod netdb_tgt_unsafe; #[path = r#"../pair/tgt_refcount.rs"#] pub mod pair_tgt_refcount; #[path = r#"../pair/tgt_unsafe.rs"#] pub mod pair_tgt_unsafe; +#[path = r#"../poll/tgt_refcount.rs"#] +pub mod poll_tgt_refcount; #[path = r#"../poll/tgt_unsafe.rs"#] pub mod poll_tgt_unsafe; +#[path = r#"../pwd/tgt_refcount.rs"#] +pub mod pwd_tgt_refcount; #[path = r#"../pwd/tgt_unsafe.rs"#] pub mod pwd_tgt_unsafe; #[path = r#"../rustls/tgt_unsafe.rs"#] @@ -96,8 +108,12 @@ pub mod rustls_tgt_unsafe; pub mod select_tgt_unsafe; #[path = r#"../signal/tgt_unsafe.rs"#] pub mod signal_tgt_unsafe; +#[path = r#"../socket/tgt_refcount.rs"#] +pub mod socket_tgt_refcount; #[path = r#"../socket/tgt_unsafe.rs"#] pub mod socket_tgt_unsafe; +#[path = r#"../stat/tgt_refcount.rs"#] +pub mod stat_tgt_refcount; #[path = r#"../stat/tgt_unsafe.rs"#] pub mod stat_tgt_unsafe; #[path = r#"../stdio/tgt_refcount.rs"#] @@ -108,8 +124,12 @@ pub mod stdio_tgt_unsafe; pub mod string_tgt_refcount; #[path = r#"../string/tgt_unsafe.rs"#] pub mod string_tgt_unsafe; +#[path = r#"../termios/tgt_refcount.rs"#] +pub mod termios_tgt_refcount; #[path = r#"../termios/tgt_unsafe.rs"#] pub mod termios_tgt_unsafe; +#[path = r#"../time/tgt_refcount.rs"#] +pub mod time_tgt_refcount; #[path = r#"../time/tgt_unsafe.rs"#] pub mod time_tgt_unsafe; #[path = r#"../unique_ptr/tgt_refcount.rs"#] diff --git a/rules/stat/tgt_refcount.rs b/rules/stat/tgt_refcount.rs new file mode 100644 index 00000000..32856e53 --- /dev/null +++ b/rules/stat/tgt_refcount.rs @@ -0,0 +1,8 @@ +// Copyright (c) 2022-present INESC-ID. +// Distributed under the MIT license that can be found in the LICENSE file. + +use libcc2rs::*; + +fn t1() -> libcc2rs::Stat { + Default::default() +} diff --git a/rules/termios/tgt_refcount.rs b/rules/termios/tgt_refcount.rs new file mode 100644 index 00000000..1c5f47f6 --- /dev/null +++ b/rules/termios/tgt_refcount.rs @@ -0,0 +1,12 @@ +// Copyright (c) 2022-present INESC-ID. +// Distributed under the MIT license that can be found in the LICENSE file. + +use libcc2rs::*; + +fn t1() -> libcc2rs::Termios { + Default::default() +} + +fn t2() -> libcc2rs::Winsize { + Default::default() +} diff --git a/rules/time/tgt_refcount.rs b/rules/time/tgt_refcount.rs new file mode 100644 index 00000000..d5bd7893 --- /dev/null +++ b/rules/time/tgt_refcount.rs @@ -0,0 +1,16 @@ +// Copyright (c) 2022-present INESC-ID. +// Distributed under the MIT license that can be found in the LICENSE file. + +use libcc2rs::*; + +fn t1() -> libcc2rs::Tm { + Default::default() +} + +fn t2() -> libcc2rs::Timeval { + Default::default() +} + +fn t3() -> libcc2rs::Timespec { + Default::default() +} diff --git a/tests/unit/libc_struct_without_default.cpp b/tests/unit/libc_struct_without_default.cpp index 5b079bde..953d22b0 100644 --- a/tests/unit/libc_struct_without_default.cpp +++ b/tests/unit/libc_struct_without_default.cpp @@ -1,4 +1,3 @@ -// no-compile: refcount #include #include #include diff --git a/tests/unit/out/refcount/libc_struct_without_default.rs b/tests/unit/out/refcount/libc_struct_without_default.rs new file mode 100644 index 00000000..9e540565 --- /dev/null +++ b/tests/unit/out/refcount/libc_struct_without_default.rs @@ -0,0 +1,89 @@ +extern crate libcc2rs; +use libcc2rs::*; +use std::cell::RefCell; +use std::collections::BTreeMap; +use std::io::prelude::*; +use std::io::{Read, Seek, Write}; +use std::os::fd::AsFd; +use std::rc::{Rc, Weak}; +#[derive()] +pub struct UserDefined { + pub a: Value>, + pub v: Value>, +} +impl Clone for UserDefined { + fn clone(&self) -> Self { + let mut this = Self { + a: Rc::new(RefCell::new((*self.a.borrow()).clone())), + v: Rc::new(RefCell::new((*self.v.borrow()).clone())), + }; + this + } +} +impl Default for UserDefined { + fn default() -> Self { + UserDefined { + a: Rc::new(RefCell::new( + std::array::from_fn::<_, 1, _>(|_| Default::default()).to_vec(), + )), + v: Rc::new(RefCell::new(Default::default())), + } + } +} +impl ByteRepr for UserDefined {} +#[derive()] +pub struct FieldIsLibcType { + pub addr: Value, +} +impl Clone for FieldIsLibcType { + fn clone(&self) -> Self { + let mut this = Self { + addr: Rc::new(RefCell::new((*self.addr.borrow()).clone())), + }; + this + } +} +impl Default for FieldIsLibcType { + fn default() -> Self { + FieldIsLibcType { + addr: Rc::new(RefCell::new(Default::default())), + } + } +} +impl ByteRepr for FieldIsLibcType {} +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let p: Value = Rc::new(RefCell::new(Default::default())); + (*(*p.borrow()).fd.borrow_mut()) = -1_i32; + (*(*p.borrow()).events.borrow_mut()) = 0_i16; + (*(*p.borrow()).revents.borrow_mut()) = 2_i16; + assert!(((*(*p.borrow()).fd.borrow()) == -1_i32)); + assert!((((*(*p.borrow()).events.borrow()) as i32) == 0)); + assert!((((*(*p.borrow()).revents.borrow()) as i32) == 2)); + let ia: Value = Rc::new(RefCell::new(Default::default())); + (*(*ia.borrow()).s_addr.borrow_mut()) = 1_u32; + assert!(((*(*ia.borrow()).s_addr.borrow()) == 1_u32)); + let t: Value = Rc::new(RefCell::new(Default::default())); + (*(*t.borrow()).tm_year.borrow_mut()) = 124; + (*(*t.borrow()).tm_mon.borrow_mut()) = 5; + (*(*t.borrow()).tm_mday.borrow_mut()) = 15; + assert!(((*(*t.borrow()).tm_year.borrow()) == 124)); + assert!(((*(*t.borrow()).tm_mon.borrow()) == 5)); + assert!(((*(*t.borrow()).tm_mday.borrow()) == 15)); + let st: Value = Rc::new(RefCell::new(Default::default())); + (*(*st.borrow()).st_size.borrow_mut()) = 1024_i64; + assert!(((*(*st.borrow()).st_size.borrow()) == 1024_i64)); + let ud: Value = Rc::new(RefCell::new(::default())); + assert!( + ((((*ud.borrow()).a.as_pointer() as Ptr) + .offset(0_usize) + .read()) + == 0) + ); + assert!(((*(*ud.borrow()).v.borrow()).len() == 0_usize)); + let filt: Value = Rc::new(RefCell::new(::default())); + assert!((((*(*(*filt.borrow()).addr.borrow()).sa_family.borrow()) as i32) == 0)); + return 0; +} From d9b446598f2bd9e4e5bec2e1de2cc87d18961c6a Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Wed, 15 Jul 2026 10:18:59 +0100 Subject: [PATCH 6/8] Use Cell instead of std::cell::Cell --- libcc2rs/src/libc_shims/dirent.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libcc2rs/src/libc_shims/dirent.rs b/libcc2rs/src/libc_shims/dirent.rs index 8ef3d3ae..f36bd5ad 100644 --- a/libcc2rs/src/libc_shims/dirent.rs +++ b/libcc2rs/src/libc_shims/dirent.rs @@ -2,7 +2,7 @@ // Distributed under the MIT license that can be found in the LICENSE file. use crate::{ByteRepr, Value}; -use std::cell::RefCell; +use std::cell::{Cell, RefCell}; use std::rc::Rc; pub struct Dirent { @@ -41,7 +41,7 @@ impl ByteRepr for Dirent {} pub struct CDir { pub entries: Vec<(u64, Vec, u8)>, - pub pos: ::std::cell::Cell, + pub pos: Cell, } impl ByteRepr for CDir {} From dcf98f7cc240eadbd15a75407185516ab8139e1e Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Wed, 15 Jul 2026 10:21:41 +0100 Subject: [PATCH 7/8] Delete to_libc/from_libc for now --- libcc2rs/src/libc_shims/socket.rs | 52 ------------------------------- libcc2rs/src/libc_shims/stat.rs | 20 ------------ 2 files changed, 72 deletions(-) diff --git a/libcc2rs/src/libc_shims/socket.rs b/libcc2rs/src/libc_shims/socket.rs index 1e815a35..5a8973af 100644 --- a/libcc2rs/src/libc_shims/socket.rs +++ b/libcc2rs/src/libc_shims/socket.rs @@ -226,58 +226,6 @@ impl ByteRepr for SockaddrStorage { } } -impl SockaddrIn { - pub fn to_libc(&self) -> ::libc::sockaddr_in { - let mut sin_zero = [0u8; 8]; - sin_zero.copy_from_slice(&self.sin_zero.borrow()); - ::libc::sockaddr_in { - sin_family: *self.sin_family.borrow(), - sin_port: *self.sin_port.borrow(), - sin_addr: ::libc::in_addr { - s_addr: *self.sin_addr.borrow().s_addr.borrow(), - }, - sin_zero, - } - } - pub fn from_libc(l: &::libc::sockaddr_in) -> Self { - Self { - sin_family: Rc::new(RefCell::new(l.sin_family)), - sin_port: Rc::new(RefCell::new(l.sin_port)), - sin_addr: Rc::new(RefCell::new(InAddr { - s_addr: Rc::new(RefCell::new(l.sin_addr.s_addr)), - })), - sin_zero: Rc::new(RefCell::new(l.sin_zero.to_vec().into_boxed_slice())), - } - } -} - -impl SockaddrIn6 { - pub fn to_libc(&self) -> ::libc::sockaddr_in6 { - let mut s6 = [0u8; 16]; - s6.copy_from_slice(&self.sin6_addr.borrow().s6_addr.borrow()); - ::libc::sockaddr_in6 { - sin6_family: *self.sin6_family.borrow(), - sin6_port: *self.sin6_port.borrow(), - sin6_flowinfo: *self.sin6_flowinfo.borrow(), - sin6_addr: ::libc::in6_addr { s6_addr: s6 }, - sin6_scope_id: *self.sin6_scope_id.borrow(), - } - } - pub fn from_libc(l: &::libc::sockaddr_in6) -> Self { - Self { - sin6_family: Rc::new(RefCell::new(l.sin6_family)), - sin6_port: Rc::new(RefCell::new(l.sin6_port)), - sin6_flowinfo: Rc::new(RefCell::new(l.sin6_flowinfo)), - sin6_addr: Rc::new(RefCell::new(In6Addr { - s6_addr: Rc::new(RefCell::new( - l.sin6_addr.s6_addr.to_vec().into_boxed_slice(), - )), - })), - sin6_scope_id: Rc::new(RefCell::new(l.sin6_scope_id)), - } - } -} - impl ByteRepr for ::libc::sockaddr {} impl ByteRepr for ::libc::sockaddr_in {} impl ByteRepr for ::libc::sockaddr_in6 {} diff --git a/libcc2rs/src/libc_shims/stat.rs b/libcc2rs/src/libc_shims/stat.rs index c98476b5..582bee23 100644 --- a/libcc2rs/src/libc_shims/stat.rs +++ b/libcc2rs/src/libc_shims/stat.rs @@ -63,24 +63,4 @@ impl Clone for Stat { impl ByteRepr for Stat {} -impl Stat { - pub fn from_libc(l: &::libc::stat) -> Self { - Self { - st_dev: Rc::new(RefCell::new(l.st_dev)), - st_ino: Rc::new(RefCell::new(l.st_ino)), - st_nlink: Rc::new(RefCell::new(l.st_nlink)), - st_mode: Rc::new(RefCell::new(l.st_mode)), - st_uid: Rc::new(RefCell::new(l.st_uid)), - st_gid: Rc::new(RefCell::new(l.st_gid)), - st_rdev: Rc::new(RefCell::new(l.st_rdev)), - st_size: Rc::new(RefCell::new(l.st_size)), - st_blksize: Rc::new(RefCell::new(l.st_blksize)), - st_blocks: Rc::new(RefCell::new(l.st_blocks)), - st_atime: Rc::new(RefCell::new(l.st_atime)), - st_mtime: Rc::new(RefCell::new(l.st_mtime)), - st_ctime: Rc::new(RefCell::new(l.st_ctime)), - } - } -} - impl ByteRepr for ::libc::stat {} From f3b3802c56102737fab36435f631a1cb5819db6b Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Wed, 15 Jul 2026 10:28:42 +0100 Subject: [PATCH 8/8] Derive Default instead of implementing it --- libcc2rs/src/libc_shims/ifaddrs.rs | 13 +--------- libcc2rs/src/libc_shims/netdb.rs | 16 +----------- libcc2rs/src/libc_shims/poll.rs | 11 +-------- libcc2rs/src/libc_shims/pwd.rs | 15 +----------- libcc2rs/src/libc_shims/socket.rs | 13 +--------- libcc2rs/src/libc_shims/stat.rs | 21 +--------------- libcc2rs/src/libc_shims/termios.rs | 12 +-------- libcc2rs/src/libc_shims/time.rs | 39 +++--------------------------- 8 files changed, 10 insertions(+), 130 deletions(-) diff --git a/libcc2rs/src/libc_shims/ifaddrs.rs b/libcc2rs/src/libc_shims/ifaddrs.rs index a1bde73a..33446410 100644 --- a/libcc2rs/src/libc_shims/ifaddrs.rs +++ b/libcc2rs/src/libc_shims/ifaddrs.rs @@ -6,6 +6,7 @@ use crate::{ByteRepr, Ptr, Value}; use std::cell::RefCell; use std::rc::Rc; +#[derive(Default)] pub struct Ifaddrs { pub ifa_next: Value>, pub ifa_name: Value>, @@ -14,18 +15,6 @@ pub struct Ifaddrs { pub ifa_netmask: Value>, } -impl Default for Ifaddrs { - fn default() -> Self { - Self { - ifa_next: Rc::new(RefCell::new(Ptr::null())), - ifa_name: Rc::new(RefCell::new(Ptr::null())), - ifa_flags: Rc::new(RefCell::new(0)), - ifa_addr: Rc::new(RefCell::new(Ptr::null())), - ifa_netmask: Rc::new(RefCell::new(Ptr::null())), - } - } -} - impl Clone for Ifaddrs { fn clone(&self) -> Self { Self { diff --git a/libcc2rs/src/libc_shims/netdb.rs b/libcc2rs/src/libc_shims/netdb.rs index a3ef5015..411c5f93 100644 --- a/libcc2rs/src/libc_shims/netdb.rs +++ b/libcc2rs/src/libc_shims/netdb.rs @@ -6,6 +6,7 @@ use crate::{ByteRepr, Ptr, Value}; use std::cell::RefCell; use std::rc::Rc; +#[derive(Default)] pub struct Addrinfo { pub ai_flags: Value, pub ai_family: Value, @@ -17,21 +18,6 @@ pub struct Addrinfo { pub ai_next: Value>, } -impl Default for Addrinfo { - fn default() -> Self { - Self { - ai_flags: Rc::new(RefCell::new(0)), - ai_family: Rc::new(RefCell::new(0)), - ai_socktype: Rc::new(RefCell::new(0)), - ai_protocol: Rc::new(RefCell::new(0)), - ai_addrlen: Rc::new(RefCell::new(0)), - ai_addr: Rc::new(RefCell::new(Ptr::null())), - ai_canonname: Rc::new(RefCell::new(Ptr::null())), - ai_next: Rc::new(RefCell::new(Ptr::null())), - } - } -} - impl Clone for Addrinfo { fn clone(&self) -> Self { Self { diff --git a/libcc2rs/src/libc_shims/poll.rs b/libcc2rs/src/libc_shims/poll.rs index 1634d395..51b1be84 100644 --- a/libcc2rs/src/libc_shims/poll.rs +++ b/libcc2rs/src/libc_shims/poll.rs @@ -5,22 +5,13 @@ use crate::{ByteRepr, Value}; use std::cell::RefCell; use std::rc::Rc; +#[derive(Default)] pub struct Pollfd { pub fd: Value, pub events: Value, pub revents: Value, } -impl Default for Pollfd { - fn default() -> Self { - Self { - fd: Rc::new(RefCell::new(0)), - events: Rc::new(RefCell::new(0)), - revents: Rc::new(RefCell::new(0)), - } - } -} - impl Clone for Pollfd { fn clone(&self) -> Self { Self { diff --git a/libcc2rs/src/libc_shims/pwd.rs b/libcc2rs/src/libc_shims/pwd.rs index d50fb9fe..dd76bde2 100644 --- a/libcc2rs/src/libc_shims/pwd.rs +++ b/libcc2rs/src/libc_shims/pwd.rs @@ -5,6 +5,7 @@ use crate::{ByteRepr, Ptr, Value}; use std::cell::RefCell; use std::rc::Rc; +#[derive(Default)] pub struct Passwd { pub pw_name: Value>, pub pw_passwd: Value>, @@ -15,20 +16,6 @@ pub struct Passwd { pub pw_shell: Value>, } -impl Default for Passwd { - fn default() -> Self { - Self { - pw_name: Rc::new(RefCell::new(Ptr::null())), - pw_passwd: Rc::new(RefCell::new(Ptr::null())), - pw_uid: Rc::new(RefCell::new(0)), - pw_gid: Rc::new(RefCell::new(0)), - pw_gecos: Rc::new(RefCell::new(Ptr::null())), - pw_dir: Rc::new(RefCell::new(Ptr::null())), - pw_shell: Rc::new(RefCell::new(Ptr::null())), - } - } -} - impl Clone for Passwd { fn clone(&self) -> Self { Self { diff --git a/libcc2rs/src/libc_shims/socket.rs b/libcc2rs/src/libc_shims/socket.rs index 5a8973af..73012d70 100644 --- a/libcc2rs/src/libc_shims/socket.rs +++ b/libcc2rs/src/libc_shims/socket.rs @@ -18,6 +18,7 @@ pub struct SockaddrIn { pub sin_zero: Value>, } +#[derive(Default)] pub struct SockaddrIn6 { pub sin6_family: Value, pub sin6_port: Value, @@ -56,18 +57,6 @@ impl Default for SockaddrIn { } } -impl Default for SockaddrIn6 { - fn default() -> Self { - Self { - sin6_family: Rc::new(RefCell::new(0)), - sin6_port: Rc::new(RefCell::new(0)), - sin6_flowinfo: Rc::new(RefCell::new(0)), - sin6_addr: Rc::new(RefCell::new(In6Addr::default())), - sin6_scope_id: Rc::new(RefCell::new(0)), - } - } -} - impl Default for SockaddrUn { fn default() -> Self { Self { diff --git a/libcc2rs/src/libc_shims/stat.rs b/libcc2rs/src/libc_shims/stat.rs index 582bee23..b73b6acb 100644 --- a/libcc2rs/src/libc_shims/stat.rs +++ b/libcc2rs/src/libc_shims/stat.rs @@ -5,6 +5,7 @@ use crate::{ByteRepr, Value}; use std::cell::RefCell; use std::rc::Rc; +#[derive(Default)] pub struct Stat { pub st_dev: Value, pub st_ino: Value, @@ -21,26 +22,6 @@ pub struct Stat { pub st_ctime: Value, } -impl Default for Stat { - fn default() -> Self { - Self { - st_dev: Rc::new(RefCell::new(0)), - st_ino: Rc::new(RefCell::new(0)), - st_nlink: Rc::new(RefCell::new(0)), - st_mode: Rc::new(RefCell::new(0)), - st_uid: Rc::new(RefCell::new(0)), - st_gid: Rc::new(RefCell::new(0)), - st_rdev: Rc::new(RefCell::new(0)), - st_size: Rc::new(RefCell::new(0)), - st_blksize: Rc::new(RefCell::new(0)), - st_blocks: Rc::new(RefCell::new(0)), - st_atime: Rc::new(RefCell::new(0)), - st_mtime: Rc::new(RefCell::new(0)), - st_ctime: Rc::new(RefCell::new(0)), - } - } -} - impl Clone for Stat { fn clone(&self) -> Self { Self { diff --git a/libcc2rs/src/libc_shims/termios.rs b/libcc2rs/src/libc_shims/termios.rs index 8852e968..66e3d9db 100644 --- a/libcc2rs/src/libc_shims/termios.rs +++ b/libcc2rs/src/libc_shims/termios.rs @@ -48,6 +48,7 @@ impl Clone for Termios { impl ByteRepr for Termios {} +#[derive(Default)] pub struct Winsize { pub ws_row: Value, pub ws_col: Value, @@ -55,17 +56,6 @@ pub struct Winsize { pub ws_ypixel: Value, } -impl Default for Winsize { - fn default() -> Self { - Self { - ws_row: Rc::new(RefCell::new(0)), - ws_col: Rc::new(RefCell::new(0)), - ws_xpixel: Rc::new(RefCell::new(0)), - ws_ypixel: Rc::new(RefCell::new(0)), - } - } -} - impl Clone for Winsize { fn clone(&self) -> Self { Self { diff --git a/libcc2rs/src/libc_shims/time.rs b/libcc2rs/src/libc_shims/time.rs index c581edfc..10fa6cfd 100644 --- a/libcc2rs/src/libc_shims/time.rs +++ b/libcc2rs/src/libc_shims/time.rs @@ -5,6 +5,7 @@ use crate::{ByteRepr, Ptr, Value}; use std::cell::RefCell; use std::rc::Rc; +#[derive(Default)] pub struct Tm { pub tm_sec: Value, pub tm_min: Value, @@ -19,24 +20,6 @@ pub struct Tm { pub tm_zone: Value>, } -impl Default for Tm { - fn default() -> Self { - Self { - tm_sec: Rc::new(RefCell::new(0)), - tm_min: Rc::new(RefCell::new(0)), - tm_hour: Rc::new(RefCell::new(0)), - tm_mday: Rc::new(RefCell::new(0)), - tm_mon: Rc::new(RefCell::new(0)), - tm_year: Rc::new(RefCell::new(0)), - tm_wday: Rc::new(RefCell::new(0)), - tm_yday: Rc::new(RefCell::new(0)), - tm_isdst: Rc::new(RefCell::new(0)), - tm_gmtoff: Rc::new(RefCell::new(0)), - tm_zone: Rc::new(RefCell::new(Ptr::null())), - } - } -} - impl Clone for Tm { fn clone(&self) -> Self { Self { @@ -57,20 +40,12 @@ impl Clone for Tm { impl ByteRepr for Tm {} +#[derive(Default)] pub struct Timeval { pub tv_sec: Value, pub tv_usec: Value, } -impl Default for Timeval { - fn default() -> Self { - Self { - tv_sec: Rc::new(RefCell::new(0)), - tv_usec: Rc::new(RefCell::new(0)), - } - } -} - impl Clone for Timeval { fn clone(&self) -> Self { Self { @@ -82,20 +57,12 @@ impl Clone for Timeval { impl ByteRepr for Timeval {} +#[derive(Default)] pub struct Timespec { pub tv_sec: Value, pub tv_nsec: Value, } -impl Default for Timespec { - fn default() -> Self { - Self { - tv_sec: Rc::new(RefCell::new(0)), - tv_nsec: Rc::new(RefCell::new(0)), - } - } -} - impl Clone for Timespec { fn clone(&self) -> Self { Self {