Skip to content

Commit

Permalink
(c2rust-analyze) Add known_fns! for declaring the permissions on …
Browse files Browse the repository at this point in the history
…ptrs in known (i.e. `libc`) `UnknownDef` `fn`s (#978)

I wrote this as a `macro_rules!` macro so that we can write the pointer
permission annotations inline with what the normal `extern` declaration
would look like. The macro checks that the declaration matches `libc`'s
(or wherever it could be from) and that there are the correct number of
`PermissionSet`s on each type corresponding to the number of pointers
directly in that type (i.e., the number of `*`).

The syntax for this is an optional `: [PERM1a | PERM1b, PERM2a | PERM2b
| PERM2c]` after each type in a `fn` signature, where the order of the
`PermissionSet`s corresponds to the pointers in the type in
left-to-right order. For example:

```rust
known_fns! {
    mod libc {

        #[cfg(target_os = "linux")]
        fn __errno_location() -> *mut c_int: [READ | WRITE];

        #[cfg(target_os = "macos")]
        fn __error() -> *mut c_int: [READ | WRITE];

        fn _exit(
            status: c_int,
        ) -> !;

        fn abort() -> !;

        fn abs(
            i: c_int,
        ) -> c_int;

        fn accept(
            socket: c_int,
            address: *mut sockaddr: [WRITE],
            address_len: *mut socklen_t: [READ | WRITE],
        ) -> c_int;

        fn read(
            fd: c_int,
            buf: *mut c_void: [WRITE | OFFSET_ADD],
            count: size_t,
        ) -> ssize_t;

        fn write(
            fd: c_int,
            buf: *const c_void: [READ | OFFSET_ADD],
            count: size_t,
        ) -> ssize_t;

        fn strtol(
            s: *const c_char: [READ | OFFSET_ADD],
            endp: *mut *mut c_char: [WRITE, WRITE | OFFSET_ADD],
            base: c_int,
        ) -> c_long;

    }
};
```

I'm still working on the integration of these `KnownFn`s into `fn_sigs`
as `LFnSig`s, but I wanted to open a separate PR for how they are
declared in the first place.
  • Loading branch information
kkysen authored Jul 7, 2023
2 parents 1f8e1f5 + b9ef5a0 commit c02f2c2
Show file tree
Hide file tree
Showing 5 changed files with 481 additions and 2 deletions.
5 changes: 3 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions c2rust-analyze/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ env_logger = "0.10.0"
log = "0.4.17"
backtrace = "0.3.67"
itertools = "0.10"
libc = "0.2.147"

[build-dependencies]
c2rust-build-paths = { path = "../c2rust-build-paths", version = "0.18.0" }
Expand Down
11 changes: 11 additions & 0 deletions c2rust-analyze/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,17 @@ impl PermissionSet {
//
// `.union` is used here since it's a `const fn`, unlike `BitOr::bitor`.
pub const STRING_LITERAL: Self = Self::READ.union(Self::OFFSET_ADD);

#[cfg(test)]
pub const fn union_all<const N: usize>(a: [Self; N]) -> Self {
let mut this = Self::empty();
let mut i = 0;
while i < N {
this = this.union(a[i]);
i += 1;
}
this
}
}

bitflags! {
Expand Down
Loading

0 comments on commit c02f2c2

Please sign in to comment.