xref: /qemu/rust/qemu-api/src/module.rs (revision e3a207722b783675b362db4ae22a449f42a26b24)
1 // Copyright 2024, Linaro Limited
2 // Author(s): Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
3 // SPDX-License-Identifier: GPL-2.0-or-later
4 
5 //! Macro to register blocks of code that run as QEMU starts up.
6 
7 #[macro_export]
8 macro_rules! module_init {
9     ($type:ident => $body:block) => {
10         const _: () = {
11             #[used]
12             #[cfg_attr(
13                 not(any(target_vendor = "apple", target_os = "windows")),
14                 link_section = ".init_array"
15             )]
16             #[cfg_attr(target_vendor = "apple", link_section = "__DATA,__mod_init_func")]
17             #[cfg_attr(target_os = "windows", link_section = ".CRT$XCU")]
18             pub static LOAD_MODULE: extern "C" fn() = {
19                 extern "C" fn init_fn() {
20                     $body
21                 }
22 
23                 extern "C" fn ctor_fn() {
24                     unsafe {
25                         $crate::bindings::register_module_init(
26                             Some(init_fn),
27                             $crate::bindings::module_init_type::$type,
28                         );
29                     }
30                 }
31 
32                 ctor_fn
33             };
34         };
35     };
36 
37     // shortcut because it's quite common that $body needs unsafe {}
38     ($type:ident => unsafe $body:block) => {
39         $crate::module_init! {
40             $type => { unsafe { $body } }
41         }
42     };
43 }
44