Skip to content

Commit 571f697

Browse files
authored
Add rules for libc structs (#257)
This adds rules for both unsafe and recount libc structs. For unsafe the rule is trivial: ```rs fn t1() -> libc::sockaddr { unsafe { std::mem::zeroed() } } ``` For refcount, I added a new dir in libcc2rs, called libc_shims. It defines refcount shim structs for each libc struct, for example: ```rs pub struct Sockaddr { pub sa_family: Value<u16>, pub sa_data: Value<Box<[u8]>>, } ``` The shims exist for 2 reasons: * generated code expects each field to be boxed * libc fields can contain raw pointers, which are not permitted in refcount The refcount rule for sockaddr becomes: ```rs fn t1() -> libcc2rs::Sockaddr { Default::default() } ```
1 parent 12c7116 commit 571f697

49 files changed

Lines changed: 1038 additions & 17 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

libcc2rs/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ pub use reinterpret::ByteRepr;
77
mod rc;
88
pub use rc::*;
99

10+
mod libc_shims;
11+
pub use libc_shims::*;
12+
1013
mod fn_ptr;
1114
pub use fn_ptr::FnPtr;
1215

libcc2rs/src/libc_shims/dirent.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright (c) 2022-present INESC-ID.
2+
// Distributed under the MIT license that can be found in the LICENSE file.
3+
4+
use crate::{ByteRepr, Value};
5+
use std::cell::{Cell, RefCell};
6+
use std::rc::Rc;
7+
8+
pub struct Dirent {
9+
pub d_ino: Value<u64>,
10+
pub d_off: Value<i64>,
11+
pub d_reclen: Value<u16>,
12+
pub d_type: Value<u8>,
13+
pub d_name: Value<Box<[u8]>>,
14+
}
15+
16+
impl Default for Dirent {
17+
fn default() -> Self {
18+
Self {
19+
d_ino: Rc::new(RefCell::new(0)),
20+
d_off: Rc::new(RefCell::new(0)),
21+
d_reclen: Rc::new(RefCell::new(0)),
22+
d_type: Rc::new(RefCell::new(0)),
23+
d_name: Rc::new(RefCell::new(vec![0u8; 256].into_boxed_slice())),
24+
}
25+
}
26+
}
27+
28+
impl Clone for Dirent {
29+
fn clone(&self) -> Self {
30+
Self {
31+
d_ino: Rc::new(RefCell::new(*self.d_ino.borrow())),
32+
d_off: Rc::new(RefCell::new(*self.d_off.borrow())),
33+
d_reclen: Rc::new(RefCell::new(*self.d_reclen.borrow())),
34+
d_type: Rc::new(RefCell::new(*self.d_type.borrow())),
35+
d_name: Rc::new(RefCell::new(self.d_name.borrow().clone())),
36+
}
37+
}
38+
}
39+
40+
impl ByteRepr for Dirent {}
41+
42+
pub struct CDir {
43+
pub entries: Vec<(u64, Vec<u8>, u8)>,
44+
pub pos: Cell<usize>,
45+
}
46+
47+
impl ByteRepr for CDir {}
48+
49+
impl ByteRepr for ::libc::dirent {}

libcc2rs/src/libc_shims/ifaddrs.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright (c) 2022-present INESC-ID.
2+
// Distributed under the MIT license that can be found in the LICENSE file.
3+
4+
use super::Sockaddr;
5+
use crate::{ByteRepr, Ptr, Value};
6+
use std::cell::RefCell;
7+
use std::rc::Rc;
8+
9+
#[derive(Default)]
10+
pub struct Ifaddrs {
11+
pub ifa_next: Value<Ptr<Ifaddrs>>,
12+
pub ifa_name: Value<Ptr<u8>>,
13+
pub ifa_flags: Value<u32>,
14+
pub ifa_addr: Value<Ptr<Sockaddr>>,
15+
pub ifa_netmask: Value<Ptr<Sockaddr>>,
16+
}
17+
18+
impl Clone for Ifaddrs {
19+
fn clone(&self) -> Self {
20+
Self {
21+
ifa_next: Rc::new(RefCell::new(self.ifa_next.borrow().clone())),
22+
ifa_name: Rc::new(RefCell::new(self.ifa_name.borrow().clone())),
23+
ifa_flags: Rc::new(RefCell::new(*self.ifa_flags.borrow())),
24+
ifa_addr: Rc::new(RefCell::new(self.ifa_addr.borrow().clone())),
25+
ifa_netmask: Rc::new(RefCell::new(self.ifa_netmask.borrow().clone())),
26+
}
27+
}
28+
}
29+
30+
impl ByteRepr for Ifaddrs {}
31+
32+
impl ByteRepr for ::libc::ifaddrs {}

libcc2rs/src/libc_shims/ip.rs

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// Copyright (c) 2022-present INESC-ID.
2+
// Distributed under the MIT license that can be found in the LICENSE file.
3+
4+
use crate::{AsPointer, ByteRepr, Ptr, Value};
5+
use std::cell::RefCell;
6+
use std::rc::Rc;
7+
8+
#[derive(Default)]
9+
pub struct InAddr {
10+
pub s_addr: Value<u32>,
11+
}
12+
13+
pub struct In6Addr {
14+
pub s6_addr: Value<Box<[u8]>>,
15+
}
16+
17+
impl In6Addr {
18+
pub fn s6_addr(&self) -> Ptr<u8> {
19+
self.s6_addr.as_pointer()
20+
}
21+
}
22+
23+
impl Default for In6Addr {
24+
fn default() -> Self {
25+
Self {
26+
s6_addr: Rc::new(RefCell::new(vec![0u8; 16].into_boxed_slice())),
27+
}
28+
}
29+
}
30+
31+
impl Clone for InAddr {
32+
fn clone(&self) -> Self {
33+
Self {
34+
s_addr: Rc::new(RefCell::new(*self.s_addr.borrow())),
35+
}
36+
}
37+
}
38+
39+
impl Clone for In6Addr {
40+
fn clone(&self) -> Self {
41+
Self {
42+
s6_addr: Rc::new(RefCell::new(self.s6_addr.borrow().clone())),
43+
}
44+
}
45+
}
46+
47+
impl ByteRepr for InAddr {
48+
fn byte_size() -> usize {
49+
4
50+
}
51+
fn to_bytes(&self, buf: &mut [u8]) {
52+
(*self.s_addr.borrow()).to_bytes(&mut buf[0..4]);
53+
}
54+
fn from_bytes(buf: &[u8]) -> Self {
55+
Self {
56+
s_addr: Rc::new(RefCell::new(<u32>::from_bytes(&buf[0..4]))),
57+
}
58+
}
59+
}
60+
61+
impl ByteRepr for In6Addr {
62+
fn byte_size() -> usize {
63+
16
64+
}
65+
fn to_bytes(&self, buf: &mut [u8]) {
66+
buf[0..16].copy_from_slice(&self.s6_addr.borrow());
67+
}
68+
fn from_bytes(buf: &[u8]) -> Self {
69+
Self {
70+
s6_addr: Rc::new(RefCell::new(buf[0..16].to_vec().into_boxed_slice())),
71+
}
72+
}
73+
}
74+
75+
impl ByteRepr for ::libc::in_addr {}
76+
impl ByteRepr for ::libc::in6_addr {}

libcc2rs/src/libc_shims/mod.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright (c) 2022-present INESC-ID.
2+
// Distributed under the MIT license that can be found in the LICENSE file.
3+
4+
mod dirent;
5+
mod ifaddrs;
6+
mod ip;
7+
mod netdb;
8+
mod poll;
9+
mod pwd;
10+
mod socket;
11+
mod stat;
12+
mod termios;
13+
mod time;
14+
15+
pub use dirent::*;
16+
pub use ifaddrs::*;
17+
pub use ip::*;
18+
pub use netdb::*;
19+
pub use poll::*;
20+
pub use pwd::*;
21+
pub use socket::*;
22+
pub use stat::*;
23+
pub use termios::*;
24+
pub use time::*;

libcc2rs/src/libc_shims/netdb.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright (c) 2022-present INESC-ID.
2+
// Distributed under the MIT license that can be found in the LICENSE file.
3+
4+
use super::Sockaddr;
5+
use crate::{ByteRepr, Ptr, Value};
6+
use std::cell::RefCell;
7+
use std::rc::Rc;
8+
9+
#[derive(Default)]
10+
pub struct Addrinfo {
11+
pub ai_flags: Value<i32>,
12+
pub ai_family: Value<i32>,
13+
pub ai_socktype: Value<i32>,
14+
pub ai_protocol: Value<i32>,
15+
pub ai_addrlen: Value<u32>,
16+
pub ai_addr: Value<Ptr<Sockaddr>>,
17+
pub ai_canonname: Value<Ptr<u8>>,
18+
pub ai_next: Value<Ptr<Addrinfo>>,
19+
}
20+
21+
impl Clone for Addrinfo {
22+
fn clone(&self) -> Self {
23+
Self {
24+
ai_flags: Rc::new(RefCell::new(*self.ai_flags.borrow())),
25+
ai_family: Rc::new(RefCell::new(*self.ai_family.borrow())),
26+
ai_socktype: Rc::new(RefCell::new(*self.ai_socktype.borrow())),
27+
ai_protocol: Rc::new(RefCell::new(*self.ai_protocol.borrow())),
28+
ai_addrlen: Rc::new(RefCell::new(*self.ai_addrlen.borrow())),
29+
ai_addr: Rc::new(RefCell::new(self.ai_addr.borrow().clone())),
30+
ai_canonname: Rc::new(RefCell::new(self.ai_canonname.borrow().clone())),
31+
ai_next: Rc::new(RefCell::new(self.ai_next.borrow().clone())),
32+
}
33+
}
34+
}
35+
36+
impl ByteRepr for Addrinfo {}
37+
38+
impl ByteRepr for ::libc::addrinfo {}

libcc2rs/src/libc_shims/poll.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright (c) 2022-present INESC-ID.
2+
// Distributed under the MIT license that can be found in the LICENSE file.
3+
4+
use crate::{ByteRepr, Value};
5+
use std::cell::RefCell;
6+
use std::rc::Rc;
7+
8+
#[derive(Default)]
9+
pub struct Pollfd {
10+
pub fd: Value<i32>,
11+
pub events: Value<i16>,
12+
pub revents: Value<i16>,
13+
}
14+
15+
impl Clone for Pollfd {
16+
fn clone(&self) -> Self {
17+
Self {
18+
fd: Rc::new(RefCell::new(*self.fd.borrow())),
19+
events: Rc::new(RefCell::new(*self.events.borrow())),
20+
revents: Rc::new(RefCell::new(*self.revents.borrow())),
21+
}
22+
}
23+
}
24+
25+
impl ByteRepr for Pollfd {}
26+
27+
impl ByteRepr for ::libc::pollfd {}

libcc2rs/src/libc_shims/pwd.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright (c) 2022-present INESC-ID.
2+
// Distributed under the MIT license that can be found in the LICENSE file.
3+
4+
use crate::{ByteRepr, Ptr, Value};
5+
use std::cell::RefCell;
6+
use std::rc::Rc;
7+
8+
#[derive(Default)]
9+
pub struct Passwd {
10+
pub pw_name: Value<Ptr<u8>>,
11+
pub pw_passwd: Value<Ptr<u8>>,
12+
pub pw_uid: Value<u32>,
13+
pub pw_gid: Value<u32>,
14+
pub pw_gecos: Value<Ptr<u8>>,
15+
pub pw_dir: Value<Ptr<u8>>,
16+
pub pw_shell: Value<Ptr<u8>>,
17+
}
18+
19+
impl Clone for Passwd {
20+
fn clone(&self) -> Self {
21+
Self {
22+
pw_name: Rc::new(RefCell::new(self.pw_name.borrow().clone())),
23+
pw_passwd: Rc::new(RefCell::new(self.pw_passwd.borrow().clone())),
24+
pw_uid: Rc::new(RefCell::new(*self.pw_uid.borrow())),
25+
pw_gid: Rc::new(RefCell::new(*self.pw_gid.borrow())),
26+
pw_gecos: Rc::new(RefCell::new(self.pw_gecos.borrow().clone())),
27+
pw_dir: Rc::new(RefCell::new(self.pw_dir.borrow().clone())),
28+
pw_shell: Rc::new(RefCell::new(self.pw_shell.borrow().clone())),
29+
}
30+
}
31+
}
32+
33+
impl ByteRepr for Passwd {}
34+
35+
impl ByteRepr for ::libc::passwd {}

0 commit comments

Comments
 (0)