| 1 | // SPDX-License-Identifier: MIT |
| 2 | |
| 3 | //! ## Opaque wrappers |
| 4 | //! |
| 5 | //! The cell types from the previous section are useful at the boundaries |
| 6 | //! of code that requires interior mutability. When writing glue code that |
| 7 | //! interacts directly with C structs, however, it is useful to operate |
| 8 | //! at a lower level. |
| 9 | //! |
| 10 | //! C functions often violate Rust's fundamental assumptions about memory |
| 11 | //! safety by modifying memory even if it is shared. Furthermore, C structs |
| 12 | //! often start their life uninitialized and may be populated lazily. |
| 13 | //! |
| 14 | //! For this reason, this module provides the [`Opaque<T>`] type to opt out |
| 15 | //! of Rust's usual guarantees about the wrapped type. Access to the wrapped |
| 16 | //! value is always through raw pointers, obtained via methods like |
| 17 | //! [`as_mut_ptr()`](Opaque::as_mut_ptr) and [`as_ptr()`](Opaque::as_ptr). These |
| 18 | //! pointers can then be passed to C functions or dereferenced; both actions |
| 19 | //! require `unsafe` blocks, making it clear where safety guarantees must be |
| 20 | //! manually verified. For example |
| 21 | //! |
| 22 | //! ```ignore |
| 23 | //! unsafe { |
| 24 | //! let state = Opaque::<MyStruct>::uninit(); |
| 25 | //! qemu_struct_init(state.as_mut_ptr()); |
| 26 | //! } |
| 27 | //! ``` |
| 28 | //! |
| 29 | //! [`Opaque<T>`] will usually be wrapped one level further, so that |
| 30 | //! bridge methods can be added to the wrapper: |
| 31 | //! |
| 32 | //! ```ignore |
| 33 | //! pub struct MyStruct(Opaque<bindings::MyStruct>); |
| 34 | //! |
| 35 | //! impl MyStruct { |
| 36 | //! fn new() -> Pin<Box<MyStruct>> { |
| 37 | //! let result = Box::pin(unsafe { Opaque::uninit() }); |
| 38 | //! unsafe { qemu_struct_init(result.as_mut_ptr()) }; |
| 39 | //! result |
| 40 | //! } |
| 41 | //! } |
| 42 | //! ``` |
| 43 | //! |
| 44 | //! This pattern of wrapping bindgen-generated types in [`Opaque<T>`] provides |
| 45 | //! several advantages: |
| 46 | //! |
| 47 | //! * The choice of traits to be implemented is not limited by the |
| 48 | //! bindgen-generated code. For example, [`Drop`] can be added without |
| 49 | //! disabling [`Copy`] on the underlying bindgen type |
| 50 | //! |
| 51 | //! * [`Send`] and [`Sync`] implementations can be controlled by the wrapper |
| 52 | //! type rather than being automatically derived from the C struct's layout |
| 53 | //! |
| 54 | //! * Methods can be implemented in a separate crate from the bindgen-generated |
| 55 | //! bindings |
| 56 | //! |
| 57 | //! * [`Debug`](std::fmt::Debug) and [`Display`](std::fmt::Display) |
| 58 | //! implementations can be customized to be more readable than the raw C |
| 59 | //! struct representation |
| 60 | //! |
| 61 | //! The [`Opaque<T>`] type does not include BQL validation; it is possible to |
| 62 | //! assert in the code that the right lock is taken, to use it together |
| 63 | //! with a custom lock guard type, or to let C code take the lock, as |
| 64 | //! appropriate. It is also possible to use it with non-thread-safe |
| 65 | //! types, since by default (unlike [`BqlCell`] and [`BqlRefCell`] |
| 66 | //! it is neither `Sync` nor `Send`. |
| 67 | //! |
| 68 | //! While [`Opaque<T>`] is necessary for C interop, it should be used sparingly |
| 69 | //! and only at FFI boundaries. For QEMU-specific types that need interior |
| 70 | //! mutability, prefer [`BqlCell`] or [`BqlRefCell`]. |
| 71 | //! |
| 72 | //! [`BqlCell`]: ../../bql/cell/struct.BqlCell.html |
| 73 | //! [`BqlRefCell`]: ../../bql/cell/struct.BqlRefCell.html |
| 74 | use std::{cell::UnsafeCell, fmt, marker::PhantomPinned, mem::MaybeUninit, ptr::NonNull}; |
| 75 | |
| 76 | /// Stores an opaque value that is shared with C code. |
| 77 | /// |
| 78 | /// Often, C structs can changed when calling a C function even if they are |
| 79 | /// behind a shared Rust reference, or they can be initialized lazily and have |
| 80 | /// invalid bit patterns (e.g. `3` for a [`bool`]). This goes against Rust's |
| 81 | /// strict aliasing rules, which normally prevent mutation through shared |
| 82 | /// references. |
| 83 | /// |
| 84 | /// Wrapping the struct with `Opaque<T>` ensures that the Rust compiler does not |
| 85 | /// assume the usual constraints that Rust structs require, and allows using |
| 86 | /// shared references on the Rust side. |
| 87 | /// |
| 88 | /// `Opaque<T>` is `#[repr(transparent)]`, so that it matches the memory layout |
| 89 | /// of `T`. |
| 90 | #[repr(transparent)] |
| 91 | pub struct Opaque<T> { |
| 92 | value: UnsafeCell<MaybeUninit<T>>, |
| 93 | // PhantomPinned also allows multiple references to the `Opaque<T>`, i.e. |
| 94 | // one `&mut Opaque<T>` can coexist with a `&mut T` or any number of `&T`; |
| 95 | // see https://docs.rs/pinned-aliasable/latest/pinned_aliasable/. |
| 96 | _pin: PhantomPinned, |
| 97 | } |
| 98 | |
| 99 | impl<T> Opaque<T> { |
| 100 | /// Creates a new shared reference from a C pointer |
| 101 | /// |
| 102 | /// # Safety |
| 103 | /// |
| 104 | /// The pointer must be valid, though it need not point to a valid value. |
| 105 | pub unsafe fn from_raw<'a>(ptr: *mut T) -> &'a Self { |
| 106 | let ptr = NonNull::new(ptr).unwrap().cast::<Self>(); |
| 107 | // SAFETY: Self is a transparent wrapper over T |
| 108 | unsafe { ptr.as_ref() } |
| 109 | } |
| 110 | |
| 111 | /// Creates a new opaque object with uninitialized contents. |
| 112 | /// |
| 113 | /// # Safety |
| 114 | /// |
| 115 | /// Ultimately the pointer to the returned value will be dereferenced |
| 116 | /// in another `unsafe` block, for example when passing it to a C function, |
| 117 | /// but the functions containing the dereference are usually safe. The |
| 118 | /// value returned from `uninit()` must be initialized and pinned before |
| 119 | /// calling them. |
| 120 | pub const unsafe fn uninit() -> Self { |
| 121 | Self { |
| 122 | value: UnsafeCell::new(MaybeUninit::uninit()), |
| 123 | _pin: PhantomPinned, |
| 124 | } |
| 125 | } |
| 126 | |
| 127 | /// Creates a new opaque object with zeroed contents. |
| 128 | /// |
| 129 | /// # Safety |
| 130 | /// |
| 131 | /// Ultimately the pointer to the returned value will be dereferenced |
| 132 | /// in another `unsafe` block, for example when passing it to a C function, |
| 133 | /// but the functions containing the dereference are usually safe. The |
| 134 | /// value returned from `uninit()` must be pinned (and possibly initialized) |
| 135 | /// before calling them. |
| 136 | pub const unsafe fn zeroed() -> Self { |
| 137 | Self { |
| 138 | value: UnsafeCell::new(MaybeUninit::zeroed()), |
| 139 | _pin: PhantomPinned, |
| 140 | } |
| 141 | } |
| 142 | |
| 143 | /// Returns a raw mutable pointer to the opaque data. |
| 144 | pub const fn as_mut_ptr(&self) -> *mut T { |
| 145 | UnsafeCell::get(&self.value).cast() |
| 146 | } |
| 147 | |
| 148 | /// Returns a raw pointer to the opaque data. |
| 149 | pub const fn as_ptr(&self) -> *const T { |
| 150 | self.as_mut_ptr().cast_const() |
| 151 | } |
| 152 | |
| 153 | /// Returns a raw pointer to the opaque data that can be passed to a |
| 154 | /// C function as `void *`. |
| 155 | pub const fn as_void_ptr(&self) -> *mut std::ffi::c_void { |
| 156 | UnsafeCell::get(&self.value).cast() |
| 157 | } |
| 158 | |
| 159 | /// Converts a raw pointer to the wrapped type. |
| 160 | pub const fn raw_get(slot: *mut Self) -> *mut T { |
| 161 | // Compare with Linux's raw_get method, which goes through an UnsafeCell |
| 162 | // because it takes a *const Self instead. |
| 163 | slot.cast() |
| 164 | } |
| 165 | } |
| 166 | |
| 167 | impl<T> fmt::Debug for Opaque<T> { |
| 168 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
| 169 | let mut name: String = "Opaque<".to_string(); |
| 170 | name += std::any::type_name::<T>(); |
| 171 | name += ">"; |
| 172 | f.debug_tuple(&name).field(&self.as_ptr()).finish() |
| 173 | } |
| 174 | } |
| 175 | |
| 176 | impl<T: Default> Opaque<T> { |
| 177 | /// Creates a new opaque object with default contents. |
| 178 | /// |
| 179 | /// # Safety |
| 180 | /// |
| 181 | /// Ultimately the pointer to the returned value will be dereferenced |
| 182 | /// in another `unsafe` block, for example when passing it to a C function, |
| 183 | /// but the functions containing the dereference are usually safe. The |
| 184 | /// value returned from `uninit()` must be pinned before calling them. |
| 185 | pub unsafe fn new() -> Self { |
| 186 | Self { |
| 187 | value: UnsafeCell::new(MaybeUninit::new(T::default())), |
| 188 | _pin: PhantomPinned, |
| 189 | } |
| 190 | } |
| 191 | } |
| 192 | |
| 193 | /// Annotates [`Self`] as a transparent wrapper for another type. |
| 194 | /// |
| 195 | /// Usually defined via the [`crate::Wrapper`] derive macro. |
| 196 | /// |
| 197 | /// # Examples |
| 198 | /// |
| 199 | /// ``` |
| 200 | /// # use std::mem::ManuallyDrop; |
| 201 | /// # use common::opaque::Wrapper; |
| 202 | /// #[repr(transparent)] |
| 203 | /// pub struct Example { |
| 204 | /// inner: ManuallyDrop<String>, |
| 205 | /// } |
| 206 | /// |
| 207 | /// unsafe impl Wrapper for Example { |
| 208 | /// type Wrapped = String; |
| 209 | /// } |
| 210 | /// ``` |
| 211 | /// |
| 212 | /// # Safety |
| 213 | /// |
| 214 | /// `Self` must be a `#[repr(transparent)]` wrapper for the `Wrapped` type, |
| 215 | /// whether directly or indirectly. |
| 216 | /// |
| 217 | /// # Methods |
| 218 | /// |
| 219 | /// By convention, types that implement Wrapper also implement the following |
| 220 | /// methods: |
| 221 | /// |
| 222 | /// ```ignore |
| 223 | /// pub const unsafe fn from_raw<'a>(value: *mut Self::Wrapped) -> &'a Self; |
| 224 | /// pub const unsafe fn as_mut_ptr(&self) -> *mut Self::Wrapped; |
| 225 | /// pub const unsafe fn as_ptr(&self) -> *const Self::Wrapped; |
| 226 | /// pub const unsafe fn raw_get(slot: *mut Self) -> *const Self::Wrapped; |
| 227 | /// ``` |
| 228 | /// |
| 229 | /// They are not defined here to allow them to be `const`. |
| 230 | pub unsafe trait Wrapper { |
| 231 | type Wrapped; |
| 232 | } |
| 233 | |
| 234 | unsafe impl<T> Wrapper for Opaque<T> { |
| 235 | type Wrapped = T; |
| 236 | } |