|
16 | 16 | #![feature(coerce_unsized)]
|
17 | 17 | #![feature(dispatch_from_dyn)]
|
18 | 18 | #![feature(new_uninit)]
|
| 19 | +#![feature(offset_of)] |
19 | 20 | #![feature(receiver_trait)]
|
20 | 21 | #![feature(return_position_impl_trait_in_trait)]
|
21 | 22 | #![feature(unsize)]
|
@@ -113,6 +114,38 @@ impl ThisModule {
|
113 | 114 | }
|
114 | 115 | }
|
115 | 116 |
|
| 117 | +/// Produces a pointer to an object from a pointer to one of its fields. |
| 118 | +/// |
| 119 | +/// # Safety |
| 120 | +/// |
| 121 | +/// Callers must ensure that the pointer to the field is in fact a pointer to the specified field, |
| 122 | +/// as opposed to a pointer to another object of the same type. If this condition is not met, |
| 123 | +/// any dereference of the resulting pointer is UB. |
| 124 | +/// |
| 125 | +/// # Examples |
| 126 | +/// |
| 127 | +/// ``` |
| 128 | +/// # use kernel::container_of; |
| 129 | +/// struct Test { |
| 130 | +/// a: u64, |
| 131 | +/// b: u32, |
| 132 | +/// } |
| 133 | +/// |
| 134 | +/// let test = Test { a: 10, b: 20 }; |
| 135 | +/// let b_ptr = &test.b; |
| 136 | +/// let test_alias = container_of!(b_ptr, Test, b); |
| 137 | +/// assert!(core::ptr::eq(&test, test_alias)); |
| 138 | +/// ``` |
| 139 | +#[macro_export] |
| 140 | +macro_rules! container_of { |
| 141 | + ($ptr:expr, $type:ty, $($f:tt)*) => {{ |
| 142 | + let ptr = $ptr as *const _ as *const u8; |
| 143 | + let offset = ::core::mem::offset_of!($type, $($f)*); |
| 144 | + $crate::build_assert!(offset <= isize::MAX as usize); |
| 145 | + ptr.wrapping_sub(offset) as *const $type |
| 146 | + }} |
| 147 | +} |
| 148 | + |
116 | 149 | #[cfg(not(any(testlib, test)))]
|
117 | 150 | #[panic_handler]
|
118 | 151 | fn panic(info: &core::panic::PanicInfo<'_>) -> ! {
|
|
0 commit comments