oxidecomputer / opte

packets go in, packets go out, you can't explain that
Mozilla Public License 2.0
37 stars 8 forks source link

Audit Rust enums used in FFI #322

Open luqmana opened 1 year ago

luqmana commented 1 year ago

We have a lot of enum types that are passed/returned via FFI (whether it be us calling foreign functions or exposing functions called from non-Rust code) but that comes with a subtle footgun. See https://github.com/rust-lang/rust/issues/36927. We need to go over the code to make sure we're not tripping up over this.

luqmana commented 1 year ago

I think the most ergonomic one for most simple cases would be replacing the enum with a newtype + consts:

#[repr(C)]
#[derive(Copy, Clone, Eq, PartialEq)]
pub enum ddi_info_cmd_t {
    DDI_INFO_DEVT2DEVINFO = 0,
    DDI_INFO_DEVT2INSTANCE = 1,
}

becomes this instead:

#[repr(transparent)]
#[derive(Copy, Clone, Eq, PartialEq)]
pub struct  ddi_info_cmd_t(pub c_int);
impl ddi_info_cmd_t {
    pub const DDI_INFO_DEVT2DEVINFO: Self = Self(0);
    pub const DDI_INFO_DEVT2INSTANCE: Self = Self(1);
}

We get the namespaced variantsm some exhaustiveness checks and but can still cope with unknown variants.