10a65e412SManos Pitsidianakis // Copyright 2024, Linaro Limited 20a65e412SManos Pitsidianakis // Author(s): Manos Pitsidianakis <manos.pitsidianakis@linaro.org> 30a65e412SManos Pitsidianakis // SPDX-License-Identifier: GPL-2.0-or-later 40a65e412SManos Pitsidianakis 50a65e412SManos Pitsidianakis //! Helper macros to declare migration state for device models. 60a65e412SManos Pitsidianakis //! 70a65e412SManos Pitsidianakis //! Some macros are direct equivalents to the C macros declared in 80a65e412SManos Pitsidianakis //! `include/migration/vmstate.h` while 90a65e412SManos Pitsidianakis //! [`vmstate_subsections`](crate::vmstate_subsections) and 100a65e412SManos Pitsidianakis //! [`vmstate_fields`](crate::vmstate_fields) are meant to be used when 110a65e412SManos Pitsidianakis //! declaring a device model state struct. 120a65e412SManos Pitsidianakis 130a65e412SManos Pitsidianakis #[doc(alias = "VMSTATE_UNUSED_BUFFER")] 140a65e412SManos Pitsidianakis #[macro_export] 150a65e412SManos Pitsidianakis macro_rules! vmstate_unused_buffer { 160a65e412SManos Pitsidianakis ($field_exists_fn:expr, $version_id:expr, $size:expr) => {{ 170a65e412SManos Pitsidianakis $crate::bindings::VMStateField { 180a65e412SManos Pitsidianakis name: c"unused".as_ptr(), 190a65e412SManos Pitsidianakis err_hint: ::core::ptr::null(), 200a65e412SManos Pitsidianakis offset: 0, 210a65e412SManos Pitsidianakis size: $size, 220a65e412SManos Pitsidianakis start: 0, 230a65e412SManos Pitsidianakis num: 0, 240a65e412SManos Pitsidianakis num_offset: 0, 250a65e412SManos Pitsidianakis size_offset: 0, 260a65e412SManos Pitsidianakis info: unsafe { ::core::ptr::addr_of!($crate::bindings::vmstate_info_unused_buffer) }, 270a65e412SManos Pitsidianakis flags: VMStateFlags::VMS_BUFFER, 280a65e412SManos Pitsidianakis vmsd: ::core::ptr::null(), 290a65e412SManos Pitsidianakis version_id: $version_id, 300a65e412SManos Pitsidianakis struct_version_id: 0, 310a65e412SManos Pitsidianakis field_exists: $field_exists_fn, 320a65e412SManos Pitsidianakis } 330a65e412SManos Pitsidianakis }}; 340a65e412SManos Pitsidianakis } 350a65e412SManos Pitsidianakis 360a65e412SManos Pitsidianakis #[doc(alias = "VMSTATE_UNUSED_V")] 370a65e412SManos Pitsidianakis #[macro_export] 380a65e412SManos Pitsidianakis macro_rules! vmstate_unused_v { 390a65e412SManos Pitsidianakis ($version_id:expr, $size:expr) => {{ 400a65e412SManos Pitsidianakis $crate::vmstate_unused_buffer!(None, $version_id, $size) 410a65e412SManos Pitsidianakis }}; 420a65e412SManos Pitsidianakis } 430a65e412SManos Pitsidianakis 440a65e412SManos Pitsidianakis #[doc(alias = "VMSTATE_UNUSED")] 450a65e412SManos Pitsidianakis #[macro_export] 460a65e412SManos Pitsidianakis macro_rules! vmstate_unused { 470a65e412SManos Pitsidianakis ($size:expr) => {{ 480a65e412SManos Pitsidianakis $crate::vmstate_unused_v!(0, $size) 490a65e412SManos Pitsidianakis }}; 500a65e412SManos Pitsidianakis } 510a65e412SManos Pitsidianakis 520a65e412SManos Pitsidianakis #[doc(alias = "VMSTATE_SINGLE_TEST")] 530a65e412SManos Pitsidianakis #[macro_export] 540a65e412SManos Pitsidianakis macro_rules! vmstate_single_test { 550a65e412SManos Pitsidianakis ($field_name:ident, $struct_name:ty, $field_exists_fn:expr, $version_id:expr, $info:expr, $size:expr) => {{ 560a65e412SManos Pitsidianakis $crate::bindings::VMStateField { 570a65e412SManos Pitsidianakis name: ::core::concat!(::core::stringify!($field_name), 0) 580a65e412SManos Pitsidianakis .as_bytes() 59*9f7d4520SPaolo Bonzini .as_ptr() as *const ::std::os::raw::c_char, 600a65e412SManos Pitsidianakis err_hint: ::core::ptr::null(), 610a65e412SManos Pitsidianakis offset: ::core::mem::offset_of!($struct_name, $field_name), 620a65e412SManos Pitsidianakis size: $size, 630a65e412SManos Pitsidianakis start: 0, 640a65e412SManos Pitsidianakis num: 0, 650a65e412SManos Pitsidianakis num_offset: 0, 660a65e412SManos Pitsidianakis size_offset: 0, 670a65e412SManos Pitsidianakis info: unsafe { $info }, 680a65e412SManos Pitsidianakis flags: VMStateFlags::VMS_SINGLE, 690a65e412SManos Pitsidianakis vmsd: ::core::ptr::null(), 700a65e412SManos Pitsidianakis version_id: $version_id, 710a65e412SManos Pitsidianakis struct_version_id: 0, 720a65e412SManos Pitsidianakis field_exists: $field_exists_fn, 730a65e412SManos Pitsidianakis } 740a65e412SManos Pitsidianakis }}; 750a65e412SManos Pitsidianakis } 760a65e412SManos Pitsidianakis 770a65e412SManos Pitsidianakis #[doc(alias = "VMSTATE_SINGLE")] 780a65e412SManos Pitsidianakis #[macro_export] 790a65e412SManos Pitsidianakis macro_rules! vmstate_single { 800a65e412SManos Pitsidianakis ($field_name:ident, $struct_name:ty, $version_id:expr, $info:expr, $size:expr) => {{ 810a65e412SManos Pitsidianakis $crate::vmstate_single_test!($field_name, $struct_name, None, $version_id, $info, $size) 820a65e412SManos Pitsidianakis }}; 830a65e412SManos Pitsidianakis } 840a65e412SManos Pitsidianakis 850a65e412SManos Pitsidianakis #[doc(alias = "VMSTATE_UINT32_V")] 860a65e412SManos Pitsidianakis #[macro_export] 870a65e412SManos Pitsidianakis macro_rules! vmstate_uint32_v { 880a65e412SManos Pitsidianakis ($field_name:ident, $struct_name:ty, $version_id:expr) => {{ 890a65e412SManos Pitsidianakis $crate::vmstate_single!( 900a65e412SManos Pitsidianakis $field_name, 910a65e412SManos Pitsidianakis $struct_name, 920a65e412SManos Pitsidianakis $version_id, 930a65e412SManos Pitsidianakis ::core::ptr::addr_of!($crate::bindings::vmstate_info_uint32), 940a65e412SManos Pitsidianakis ::core::mem::size_of::<u32>() 950a65e412SManos Pitsidianakis ) 960a65e412SManos Pitsidianakis }}; 970a65e412SManos Pitsidianakis } 980a65e412SManos Pitsidianakis 990a65e412SManos Pitsidianakis #[doc(alias = "VMSTATE_UINT32")] 1000a65e412SManos Pitsidianakis #[macro_export] 1010a65e412SManos Pitsidianakis macro_rules! vmstate_uint32 { 1020a65e412SManos Pitsidianakis ($field_name:ident, $struct_name:ty) => {{ 1030a65e412SManos Pitsidianakis $crate::vmstate_uint32_v!($field_name, $struct_name, 0) 1040a65e412SManos Pitsidianakis }}; 1050a65e412SManos Pitsidianakis } 1060a65e412SManos Pitsidianakis 1070a65e412SManos Pitsidianakis #[doc(alias = "VMSTATE_INT32_V")] 1080a65e412SManos Pitsidianakis #[macro_export] 1090a65e412SManos Pitsidianakis macro_rules! vmstate_int32_v { 1100a65e412SManos Pitsidianakis ($field_name:ident, $struct_name:ty, $version_id:expr) => {{ 1110a65e412SManos Pitsidianakis $crate::vmstate_single!( 1120a65e412SManos Pitsidianakis $field_name, 1130a65e412SManos Pitsidianakis $struct_name, 1140a65e412SManos Pitsidianakis $version_id, 1150a65e412SManos Pitsidianakis ::core::ptr::addr_of!($crate::bindings::vmstate_info_int32), 1160a65e412SManos Pitsidianakis ::core::mem::size_of::<i32>() 1170a65e412SManos Pitsidianakis ) 1180a65e412SManos Pitsidianakis }}; 1190a65e412SManos Pitsidianakis } 1200a65e412SManos Pitsidianakis 1210a65e412SManos Pitsidianakis #[doc(alias = "VMSTATE_INT32")] 1220a65e412SManos Pitsidianakis #[macro_export] 1230a65e412SManos Pitsidianakis macro_rules! vmstate_int32 { 1240a65e412SManos Pitsidianakis ($field_name:ident, $struct_name:ty) => {{ 1250a65e412SManos Pitsidianakis $crate::vmstate_int32_v!($field_name, $struct_name, 0) 1260a65e412SManos Pitsidianakis }}; 1270a65e412SManos Pitsidianakis } 1280a65e412SManos Pitsidianakis 1290a65e412SManos Pitsidianakis #[doc(alias = "VMSTATE_ARRAY")] 1300a65e412SManos Pitsidianakis #[macro_export] 1310a65e412SManos Pitsidianakis macro_rules! vmstate_array { 1320a65e412SManos Pitsidianakis ($field_name:ident, $struct_name:ty, $length:expr, $version_id:expr, $info:expr, $size:expr) => {{ 1330a65e412SManos Pitsidianakis $crate::bindings::VMStateField { 1340a65e412SManos Pitsidianakis name: ::core::concat!(::core::stringify!($field_name), 0) 1350a65e412SManos Pitsidianakis .as_bytes() 136*9f7d4520SPaolo Bonzini .as_ptr() as *const ::std::os::raw::c_char, 1370a65e412SManos Pitsidianakis err_hint: ::core::ptr::null(), 1380a65e412SManos Pitsidianakis offset: ::core::mem::offset_of!($struct_name, $field_name), 1390a65e412SManos Pitsidianakis size: $size, 1400a65e412SManos Pitsidianakis start: 0, 1410a65e412SManos Pitsidianakis num: $length as _, 1420a65e412SManos Pitsidianakis num_offset: 0, 1430a65e412SManos Pitsidianakis size_offset: 0, 1440a65e412SManos Pitsidianakis info: unsafe { $info }, 1450a65e412SManos Pitsidianakis flags: VMStateFlags::VMS_ARRAY, 1460a65e412SManos Pitsidianakis vmsd: ::core::ptr::null(), 1470a65e412SManos Pitsidianakis version_id: $version_id, 1480a65e412SManos Pitsidianakis struct_version_id: 0, 1490a65e412SManos Pitsidianakis field_exists: None, 1500a65e412SManos Pitsidianakis } 1510a65e412SManos Pitsidianakis }}; 1520a65e412SManos Pitsidianakis } 1530a65e412SManos Pitsidianakis 1540a65e412SManos Pitsidianakis #[doc(alias = "VMSTATE_UINT32_ARRAY_V")] 1550a65e412SManos Pitsidianakis #[macro_export] 1560a65e412SManos Pitsidianakis macro_rules! vmstate_uint32_array_v { 1570a65e412SManos Pitsidianakis ($field_name:ident, $struct_name:ty, $length:expr, $version_id:expr) => {{ 1580a65e412SManos Pitsidianakis $crate::vmstate_array!( 1590a65e412SManos Pitsidianakis $field_name, 1600a65e412SManos Pitsidianakis $struct_name, 1610a65e412SManos Pitsidianakis $length, 1620a65e412SManos Pitsidianakis $version_id, 1630a65e412SManos Pitsidianakis ::core::ptr::addr_of!($crate::bindings::vmstate_info_uint32), 1640a65e412SManos Pitsidianakis ::core::mem::size_of::<u32>() 1650a65e412SManos Pitsidianakis ) 1660a65e412SManos Pitsidianakis }}; 1670a65e412SManos Pitsidianakis } 1680a65e412SManos Pitsidianakis 1690a65e412SManos Pitsidianakis #[doc(alias = "VMSTATE_UINT32_ARRAY")] 1700a65e412SManos Pitsidianakis #[macro_export] 1710a65e412SManos Pitsidianakis macro_rules! vmstate_uint32_array { 1720a65e412SManos Pitsidianakis ($field_name:ident, $struct_name:ty, $length:expr) => {{ 1730a65e412SManos Pitsidianakis $crate::vmstate_uint32_array_v!($field_name, $struct_name, $length, 0) 1740a65e412SManos Pitsidianakis }}; 1750a65e412SManos Pitsidianakis } 1760a65e412SManos Pitsidianakis 1770a65e412SManos Pitsidianakis #[doc(alias = "VMSTATE_STRUCT_POINTER_V")] 1780a65e412SManos Pitsidianakis #[macro_export] 1790a65e412SManos Pitsidianakis macro_rules! vmstate_struct_pointer_v { 1800a65e412SManos Pitsidianakis ($field_name:ident, $struct_name:ty, $version_id:expr, $vmsd:expr, $type:ty) => {{ 1810a65e412SManos Pitsidianakis $crate::bindings::VMStateField { 1820a65e412SManos Pitsidianakis name: ::core::concat!(::core::stringify!($field_name), 0) 1830a65e412SManos Pitsidianakis .as_bytes() 184*9f7d4520SPaolo Bonzini .as_ptr() as *const ::std::os::raw::c_char, 1850a65e412SManos Pitsidianakis err_hint: ::core::ptr::null(), 1860a65e412SManos Pitsidianakis offset: ::core::mem::offset_of!($struct_name, $field_name), 1870a65e412SManos Pitsidianakis size: ::core::mem::size_of::<*const $type>(), 1880a65e412SManos Pitsidianakis start: 0, 1890a65e412SManos Pitsidianakis num: 0, 1900a65e412SManos Pitsidianakis num_offset: 0, 1910a65e412SManos Pitsidianakis size_offset: 0, 1920a65e412SManos Pitsidianakis info: ::core::ptr::null(), 1930a65e412SManos Pitsidianakis flags: VMStateFlags(VMStateFlags::VMS_STRUCT.0 | VMStateFlags::VMS_POINTER.0), 1940a65e412SManos Pitsidianakis vmsd: unsafe { $vmsd }, 1950a65e412SManos Pitsidianakis version_id: $version_id, 1960a65e412SManos Pitsidianakis struct_version_id: 0, 1970a65e412SManos Pitsidianakis field_exists: None, 1980a65e412SManos Pitsidianakis } 1990a65e412SManos Pitsidianakis }}; 2000a65e412SManos Pitsidianakis } 2010a65e412SManos Pitsidianakis 2020a65e412SManos Pitsidianakis #[doc(alias = "VMSTATE_ARRAY_OF_POINTER")] 2030a65e412SManos Pitsidianakis #[macro_export] 2040a65e412SManos Pitsidianakis macro_rules! vmstate_array_of_pointer { 2050a65e412SManos Pitsidianakis ($field_name:ident, $struct_name:ty, $num:expr, $version_id:expr, $info:expr, $type:ty) => {{ 2060a65e412SManos Pitsidianakis $crate::bindings::VMStateField { 2070a65e412SManos Pitsidianakis name: ::core::concat!(::core::stringify!($field_name), 0) 2080a65e412SManos Pitsidianakis .as_bytes() 209*9f7d4520SPaolo Bonzini .as_ptr() as *const ::std::os::raw::c_char, 2100a65e412SManos Pitsidianakis version_id: $version_id, 2110a65e412SManos Pitsidianakis num: $num as _, 2120a65e412SManos Pitsidianakis info: unsafe { $info }, 2130a65e412SManos Pitsidianakis size: ::core::mem::size_of::<*const $type>(), 2140a65e412SManos Pitsidianakis flags: VMStateFlags(VMStateFlags::VMS_ARRAY.0 | VMStateFlags::VMS_ARRAY_OF_POINTER.0), 2150a65e412SManos Pitsidianakis offset: ::core::mem::offset_of!($struct_name, $field_name), 2160a65e412SManos Pitsidianakis err_hint: ::core::ptr::null(), 2170a65e412SManos Pitsidianakis start: 0, 2180a65e412SManos Pitsidianakis num_offset: 0, 2190a65e412SManos Pitsidianakis size_offset: 0, 2200a65e412SManos Pitsidianakis vmsd: ::core::ptr::null(), 2210a65e412SManos Pitsidianakis struct_version_id: 0, 2220a65e412SManos Pitsidianakis field_exists: None, 2230a65e412SManos Pitsidianakis } 2240a65e412SManos Pitsidianakis }}; 2250a65e412SManos Pitsidianakis } 2260a65e412SManos Pitsidianakis 2270a65e412SManos Pitsidianakis #[doc(alias = "VMSTATE_ARRAY_OF_POINTER_TO_STRUCT")] 2280a65e412SManos Pitsidianakis #[macro_export] 2290a65e412SManos Pitsidianakis macro_rules! vmstate_array_of_pointer_to_struct { 2300a65e412SManos Pitsidianakis ($field_name:ident, $struct_name:ty, $num:expr, $version_id:expr, $vmsd:expr, $type:ty) => {{ 2310a65e412SManos Pitsidianakis $crate::bindings::VMStateField { 2320a65e412SManos Pitsidianakis name: ::core::concat!(::core::stringify!($field_name), 0) 2330a65e412SManos Pitsidianakis .as_bytes() 234*9f7d4520SPaolo Bonzini .as_ptr() as *const ::std::os::raw::c_char, 2350a65e412SManos Pitsidianakis version_id: $version_id, 2360a65e412SManos Pitsidianakis num: $num as _, 2370a65e412SManos Pitsidianakis vmsd: unsafe { $vmsd }, 2380a65e412SManos Pitsidianakis size: ::core::mem::size_of::<*const $type>(), 2390a65e412SManos Pitsidianakis flags: VMStateFlags( 2400a65e412SManos Pitsidianakis VMStateFlags::VMS_ARRAY.0 2410a65e412SManos Pitsidianakis | VMStateFlags::VMS_STRUCT.0 2420a65e412SManos Pitsidianakis | VMStateFlags::VMS_ARRAY_OF_POINTER.0, 2430a65e412SManos Pitsidianakis ), 2440a65e412SManos Pitsidianakis offset: ::core::mem::offset_of!($struct_name, $field_name), 2450a65e412SManos Pitsidianakis err_hint: ::core::ptr::null(), 2460a65e412SManos Pitsidianakis start: 0, 2470a65e412SManos Pitsidianakis num_offset: 0, 2480a65e412SManos Pitsidianakis size_offset: 0, 2490a65e412SManos Pitsidianakis vmsd: ::core::ptr::null(), 2500a65e412SManos Pitsidianakis struct_version_id: 0, 2510a65e412SManos Pitsidianakis field_exists: None, 2520a65e412SManos Pitsidianakis } 2530a65e412SManos Pitsidianakis }}; 2540a65e412SManos Pitsidianakis } 2550a65e412SManos Pitsidianakis 2560a65e412SManos Pitsidianakis #[doc(alias = "VMSTATE_CLOCK_V")] 2570a65e412SManos Pitsidianakis #[macro_export] 2580a65e412SManos Pitsidianakis macro_rules! vmstate_clock_v { 2590a65e412SManos Pitsidianakis ($field_name:ident, $struct_name:ty, $version_id:expr) => {{ 2600a65e412SManos Pitsidianakis $crate::vmstate_struct_pointer_v!( 2610a65e412SManos Pitsidianakis $field_name, 2620a65e412SManos Pitsidianakis $struct_name, 2630a65e412SManos Pitsidianakis $version_id, 2640a65e412SManos Pitsidianakis ::core::ptr::addr_of!($crate::bindings::vmstate_clock), 2650a65e412SManos Pitsidianakis $crate::bindings::Clock 2660a65e412SManos Pitsidianakis ) 2670a65e412SManos Pitsidianakis }}; 2680a65e412SManos Pitsidianakis } 2690a65e412SManos Pitsidianakis 2700a65e412SManos Pitsidianakis #[doc(alias = "VMSTATE_CLOCK")] 2710a65e412SManos Pitsidianakis #[macro_export] 2720a65e412SManos Pitsidianakis macro_rules! vmstate_clock { 2730a65e412SManos Pitsidianakis ($field_name:ident, $struct_name:ty) => {{ 2740a65e412SManos Pitsidianakis $crate::vmstate_clock_v!($field_name, $struct_name, 0) 2750a65e412SManos Pitsidianakis }}; 2760a65e412SManos Pitsidianakis } 2770a65e412SManos Pitsidianakis 2780a65e412SManos Pitsidianakis #[doc(alias = "VMSTATE_ARRAY_CLOCK_V")] 2790a65e412SManos Pitsidianakis #[macro_export] 2800a65e412SManos Pitsidianakis macro_rules! vmstate_array_clock_v { 2810a65e412SManos Pitsidianakis ($field_name:ident, $struct_name:ty, $num:expr, $version_id:expr) => {{ 2820a65e412SManos Pitsidianakis $crate::vmstate_array_of_pointer_to_struct!( 2830a65e412SManos Pitsidianakis $field_name, 2840a65e412SManos Pitsidianakis $struct_name, 2850a65e412SManos Pitsidianakis $num, 2860a65e412SManos Pitsidianakis $version_id, 2870a65e412SManos Pitsidianakis ::core::ptr::addr_of!($crate::bindings::vmstate_clock), 2880a65e412SManos Pitsidianakis $crate::bindings::Clock 2890a65e412SManos Pitsidianakis ) 2900a65e412SManos Pitsidianakis }}; 2910a65e412SManos Pitsidianakis } 2920a65e412SManos Pitsidianakis 2930a65e412SManos Pitsidianakis #[doc(alias = "VMSTATE_ARRAY_CLOCK")] 2940a65e412SManos Pitsidianakis #[macro_export] 2950a65e412SManos Pitsidianakis macro_rules! vmstate_array_clock { 2960a65e412SManos Pitsidianakis ($field_name:ident, $struct_name:ty, $num:expr) => {{ 2970a65e412SManos Pitsidianakis $crate::vmstate_array_clock_v!($field_name, $struct_name, $name, 0) 2980a65e412SManos Pitsidianakis }}; 2990a65e412SManos Pitsidianakis } 3000a65e412SManos Pitsidianakis 3010a65e412SManos Pitsidianakis /// Helper macro to declare a list of 3020a65e412SManos Pitsidianakis /// ([`VMStateField`](`crate::bindings::VMStateField`)) into a static and return 3030a65e412SManos Pitsidianakis /// a pointer to the array of values it created. 3040a65e412SManos Pitsidianakis #[macro_export] 3050a65e412SManos Pitsidianakis macro_rules! vmstate_fields { 3060a65e412SManos Pitsidianakis ($($field:expr),*$(,)*) => {{ 3070a65e412SManos Pitsidianakis static _FIELDS: &[$crate::bindings::VMStateField] = &[ 3080a65e412SManos Pitsidianakis $($field),*, 3090a65e412SManos Pitsidianakis $crate::bindings::VMStateField { 3100a65e412SManos Pitsidianakis name: ::core::ptr::null(), 3110a65e412SManos Pitsidianakis err_hint: ::core::ptr::null(), 3120a65e412SManos Pitsidianakis offset: 0, 3130a65e412SManos Pitsidianakis size: 0, 3140a65e412SManos Pitsidianakis start: 0, 3150a65e412SManos Pitsidianakis num: 0, 3160a65e412SManos Pitsidianakis num_offset: 0, 3170a65e412SManos Pitsidianakis size_offset: 0, 3180a65e412SManos Pitsidianakis info: ::core::ptr::null(), 3190a65e412SManos Pitsidianakis flags: VMStateFlags::VMS_END, 3200a65e412SManos Pitsidianakis vmsd: ::core::ptr::null(), 3210a65e412SManos Pitsidianakis version_id: 0, 3220a65e412SManos Pitsidianakis struct_version_id: 0, 3230a65e412SManos Pitsidianakis field_exists: None, 3240a65e412SManos Pitsidianakis } 3250a65e412SManos Pitsidianakis ]; 3260a65e412SManos Pitsidianakis _FIELDS.as_ptr() 3270a65e412SManos Pitsidianakis }} 3280a65e412SManos Pitsidianakis } 3290a65e412SManos Pitsidianakis 3300a65e412SManos Pitsidianakis /// A transparent wrapper type for the `subsections` field of 3310a65e412SManos Pitsidianakis /// [`VMStateDescription`](crate::bindings::VMStateDescription). 3320a65e412SManos Pitsidianakis /// 3330a65e412SManos Pitsidianakis /// This is necessary to be able to declare subsection descriptions as statics, 3340a65e412SManos Pitsidianakis /// because the only way to implement `Sync` for a foreign type (and `*const` 3350a65e412SManos Pitsidianakis /// pointers are foreign types in Rust) is to create a wrapper struct and 3360a65e412SManos Pitsidianakis /// `unsafe impl Sync` for it. 3370a65e412SManos Pitsidianakis /// 3380a65e412SManos Pitsidianakis /// This struct is used in the 3390a65e412SManos Pitsidianakis /// [`vm_state_subsections`](crate::vmstate_subsections) macro implementation. 3400a65e412SManos Pitsidianakis #[repr(transparent)] 3410a65e412SManos Pitsidianakis pub struct VMStateSubsectionsWrapper(pub &'static [*const crate::bindings::VMStateDescription]); 3420a65e412SManos Pitsidianakis 3430a65e412SManos Pitsidianakis unsafe impl Sync for VMStateSubsectionsWrapper {} 3440a65e412SManos Pitsidianakis 3450a65e412SManos Pitsidianakis /// Helper macro to declare a list of subsections 3460a65e412SManos Pitsidianakis /// ([`VMStateDescription`](`crate::bindings::VMStateDescription`)) into a 3470a65e412SManos Pitsidianakis /// static and return a pointer to the array of pointers it created. 3480a65e412SManos Pitsidianakis #[macro_export] 3490a65e412SManos Pitsidianakis macro_rules! vmstate_subsections { 3500a65e412SManos Pitsidianakis ($($subsection:expr),*$(,)*) => {{ 3510a65e412SManos Pitsidianakis static _SUBSECTIONS: $crate::vmstate::VMStateSubsectionsWrapper = $crate::vmstate::VMStateSubsectionsWrapper(&[ 3520a65e412SManos Pitsidianakis $({ 3530a65e412SManos Pitsidianakis static _SUBSECTION: $crate::bindings::VMStateDescription = $subsection; 3540a65e412SManos Pitsidianakis ::core::ptr::addr_of!(_SUBSECTION) 3550a65e412SManos Pitsidianakis }),*, 3560a65e412SManos Pitsidianakis ::core::ptr::null() 3570a65e412SManos Pitsidianakis ]); 3580a65e412SManos Pitsidianakis _SUBSECTIONS.0.as_ptr() 3590a65e412SManos Pitsidianakis }} 3600a65e412SManos Pitsidianakis } 361