mirror of
https://github.com/qemu/qemu.git
synced 2026-02-04 02:24:51 +00:00
rust: move binding generation to bindings/
Move raw FFI bindings generation to separate crates. This makes it possible to reuse bindgen declarations for a header file in its dependencies (this was not the case before this change), while keeping multiple -sys crates to avoid rebuilding all the code whenever something changes. Because the -sys crates are generated in dependency order, this also enforces that the crates are organized in something that resembles the dependencies between C headers. The meson.build for rust-safe crates becomes simpler, and it should be possible in the future to let Meson's cargo support handle most of it. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> [General cleanup and Python script. - Paolo] Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
committed by
Paolo Bonzini
parent
f9bbbde1ed
commit
c899071b5a
@@ -339,6 +339,63 @@ Here are some things to keep in mind when working on the QEMU Rust crate.
|
||||
or a macro) where it can be documented and tested. If needed, include
|
||||
toy versions of the code in the documentation.
|
||||
|
||||
FFI Binding Generation
|
||||
''''''''''''''''''''''
|
||||
|
||||
QEMU's Rust integration uses multiple ``*-sys`` crates that contain raw FFI
|
||||
bindings to different QEMU subsystems. These crates mirror the dependency
|
||||
structure that meson.build uses for C code, and which is reflected in
|
||||
``static_library()`` declarations. For example:
|
||||
|
||||
* util-sys: Basic utilities (no dependencies)
|
||||
* qom-sys: QEMU Object Model (depends on util-sys)
|
||||
* chardev-sys: Character devices (depends on qom-sys, util-sys)
|
||||
* hwcore-sys: Hardware core (depends on qom-sys, util-sys)
|
||||
* migration-sys: Migration (depends on util-sys)
|
||||
* system-sys: System-level APIs (depends on all others)
|
||||
|
||||
Having multiple crates avoids massive rebuilds of all Rust code when C headers
|
||||
are changed. On the other hand, bindgen is not aware of how headers are split
|
||||
across crates, and therefore it would generate declarations for dependencies
|
||||
again. These duplicate declarations are not only large, they create distinct
|
||||
types and therefore they are incompatible with each other.
|
||||
|
||||
Bindgen Configuration
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Bindgen options such as symbol blocklists or how to configure enums can be
|
||||
defined in each crate's ``Cargo.toml`` via a ``[package.metadata.bindgen]`` section.
|
||||
For example::
|
||||
|
||||
[package.metadata.bindgen]
|
||||
header = "wrapper.h" # Main header file for this crate
|
||||
rustified-enum = ["QEMUClockType"] # Enums to generate as Rust enums
|
||||
bitfield-enum = ["VMStateFlags"] # Enums to treat as bitfields
|
||||
blocklist-function = [ # Functions to exclude
|
||||
"vmstate_register_ram",
|
||||
"vmstate_unregister_ram"
|
||||
]
|
||||
additional-files = [ # Extra files to allowlist
|
||||
"include/system/memory_ldst.*"
|
||||
]
|
||||
|
||||
All bindgen options are supported in the metadata section. The complete list
|
||||
can be found in ``rust/bindings/generate_bindgen_args.py``.
|
||||
|
||||
Dependency Management
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
By examining the dependency chain before bindgen creates the code for
|
||||
the ``*-sys`` crates, the build system ensures that header files included in
|
||||
one crate are blocked from appearing in dependent crates, thus avoiding
|
||||
duplicate definitions. Dependent crates can import the definition via
|
||||
"use" statements.
|
||||
|
||||
This dependency-aware binding generation is handled automatically by
|
||||
``rust/bindings/generate_bindgen_args.py``, which processes the Cargo.toml
|
||||
files in dependency order and generates appropriate ``--allowlist-file`` and
|
||||
``--blocklist-file`` arguments for bindgen.
|
||||
|
||||
Writing procedural macros
|
||||
'''''''''''''''''''''''''
|
||||
|
||||
|
||||
@@ -4169,9 +4169,8 @@ if have_rust
|
||||
'--with-derive-default',
|
||||
'--no-layout-tests',
|
||||
'--no-prepend-enum-name',
|
||||
'--allowlist-file', meson.project_source_root() + '/include/.*',
|
||||
'--allowlist-file', meson.project_build_root() + '/.*',
|
||||
'--blocklist-file', glib_pc.get_variable('includedir') + '/glib-2.0/.*',
|
||||
'--blocklist-file', meson.project_source_root() + '/include/qemu/typedefs.h',
|
||||
'--blocklist-type', '.*_([a-z]*autoptr)$',
|
||||
]
|
||||
if not rustfmt.found()
|
||||
|
||||
68
rust/Cargo.lock
generated
68
rust/Cargo.lock
generated
@@ -59,6 +59,7 @@ name = "bql"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"glib-sys",
|
||||
"util-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -76,6 +77,7 @@ name = "chardev"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bql",
|
||||
"chardev-sys",
|
||||
"common",
|
||||
"glib-sys",
|
||||
"migration",
|
||||
@@ -83,6 +85,16 @@ dependencies = [
|
||||
"util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "chardev-sys"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"common",
|
||||
"glib-sys",
|
||||
"qom-sys",
|
||||
"util-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "common"
|
||||
version = "0.1.0"
|
||||
@@ -156,6 +168,7 @@ dependencies = [
|
||||
"chardev",
|
||||
"common",
|
||||
"glib-sys",
|
||||
"hwcore-sys",
|
||||
"migration",
|
||||
"qemu_macros",
|
||||
"qom",
|
||||
@@ -163,6 +176,19 @@ dependencies = [
|
||||
"util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hwcore-sys"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"chardev-sys",
|
||||
"common",
|
||||
"glib-sys",
|
||||
"migration-sys",
|
||||
"qom-sys",
|
||||
"system-sys",
|
||||
"util-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.11.4"
|
||||
@@ -201,10 +227,20 @@ dependencies = [
|
||||
"bql",
|
||||
"common",
|
||||
"glib-sys",
|
||||
"migration-sys",
|
||||
"qemu_macros",
|
||||
"util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "migration-sys"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"common",
|
||||
"glib-sys",
|
||||
"util-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.32"
|
||||
@@ -287,9 +323,18 @@ dependencies = [
|
||||
"glib-sys",
|
||||
"migration",
|
||||
"qemu_macros",
|
||||
"qom-sys",
|
||||
"util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "qom-sys"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"glib-sys",
|
||||
"util-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.36"
|
||||
@@ -306,6 +351,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0dca6411025b24b60bfa7ec1fe1f8e710ac09782dca409ee8237ba74b51295fd"
|
||||
dependencies = [
|
||||
"serde_core",
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -358,9 +404,12 @@ dependencies = [
|
||||
name = "system"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bql",
|
||||
"common",
|
||||
"glib-sys",
|
||||
"migration",
|
||||
"qom",
|
||||
"system-sys",
|
||||
"util",
|
||||
]
|
||||
|
||||
@@ -377,6 +426,17 @@ dependencies = [
|
||||
"version-compare",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "system-sys"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"common",
|
||||
"glib-sys",
|
||||
"migration-sys",
|
||||
"qom-sys",
|
||||
"util-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "target-lexicon"
|
||||
version = "0.13.2"
|
||||
@@ -454,6 +514,14 @@ dependencies = [
|
||||
"foreign",
|
||||
"glib-sys",
|
||||
"libc",
|
||||
"util-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "util-sys"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"glib-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -10,25 +10,25 @@ use std::{env, fs::remove_file, io::Result, path::Path};
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let manifest_dir = env!("CARGO_MANIFEST_DIR");
|
||||
let file = if let Ok(root) = env::var("MESON_BUILD_ROOT") {
|
||||
let sub = get_rust_subdir(manifest_dir).unwrap();
|
||||
format!("{root}/{sub}/bindings.inc.rs")
|
||||
} else {
|
||||
// Placing bindings.inc.rs in the source directory is supported
|
||||
// but not documented or encouraged.
|
||||
format!("{manifest_dir}/src/bindings.inc.rs")
|
||||
};
|
||||
let root = env::var("MESON_BUILD_ROOT").expect(concat!(
|
||||
"\n",
|
||||
" MESON_BUILD_ROOT not found. Maybe you wanted one of\n",
|
||||
" `make clippy`, `make rustfmt`, `make rustdoc`?\n",
|
||||
"\n",
|
||||
" For other uses of `cargo`, start a subshell with\n",
|
||||
" `pyvenv/bin/meson devenv`, or point MESON_BUILD_ROOT to\n",
|
||||
" the top of the build tree."
|
||||
));
|
||||
|
||||
let sub = get_rust_subdir(manifest_dir).unwrap();
|
||||
let file = format!("{root}/{sub}/bindings.inc.rs");
|
||||
let file = Path::new(&file);
|
||||
if !Path::new(&file).exists() {
|
||||
|
||||
if !file.exists() {
|
||||
panic!(concat!(
|
||||
"\n",
|
||||
" No generated C bindings found! Maybe you wanted one of\n",
|
||||
" `make clippy`, `make rustfmt`, `make rustdoc`?\n",
|
||||
"\n",
|
||||
" For other uses of `cargo`, start a subshell with\n",
|
||||
" `pyvenv/bin/meson devenv`, or point MESON_BUILD_ROOT to\n",
|
||||
" the top of the build tree."
|
||||
" No generated C bindings found! Run `make` first; or maybe you\n",
|
||||
" wanted one of `make clippy`, `make rustfmt`, `make rustdoc`?\n",
|
||||
));
|
||||
}
|
||||
|
||||
28
rust/bindings/chardev-sys/Cargo.toml
Normal file
28
rust/bindings/chardev-sys/Cargo.toml
Normal file
@@ -0,0 +1,28 @@
|
||||
[package]
|
||||
name = "chardev-sys"
|
||||
version = "0.1.0"
|
||||
description = "Rust sys bindings for QEMU/chardev"
|
||||
publish = false
|
||||
|
||||
authors.workspace = true
|
||||
edition.workspace = true
|
||||
homepage.workspace = true
|
||||
license.workspace = true
|
||||
repository.workspace = true
|
||||
rust-version.workspace = true
|
||||
|
||||
[lib]
|
||||
path = "lib.rs"
|
||||
|
||||
[dependencies]
|
||||
glib-sys = { workspace = true }
|
||||
common = { path = "../../common" }
|
||||
qom-sys = { path = "../qom-sys" }
|
||||
util-sys = { path = "../util-sys" }
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[package.metadata.bindgen]
|
||||
header = "wrapper.h"
|
||||
rustified-enum = ["QEMUChrEvent"]
|
||||
1
rust/bindings/chardev-sys/build.rs
Symbolic link
1
rust/bindings/chardev-sys/build.rs
Symbolic link
@@ -0,0 +1 @@
|
||||
../build.rs
|
||||
@@ -19,10 +19,9 @@
|
||||
)]
|
||||
|
||||
use common::Zeroable;
|
||||
use glib_sys::{
|
||||
gboolean, guint, GArray, GHashTable, GHashTableIter, GIOCondition, GMainContext, GPollFD,
|
||||
GPtrArray, GSList, GSource, GSourceFunc,
|
||||
};
|
||||
use glib_sys::{gboolean, guint, GIOCondition, GMainContext, GSource, GSourceFunc};
|
||||
use qom_sys::{Object, ObjectClass};
|
||||
use util_sys::{Error, IOCanReadHandler, IOReadHandler, QemuOpts};
|
||||
|
||||
#[cfg(MESON)]
|
||||
include!("bindings.inc.rs");
|
||||
12
rust/bindings/chardev-sys/meson.build
Normal file
12
rust/bindings/chardev-sys/meson.build
Normal file
@@ -0,0 +1,12 @@
|
||||
_bindgen_chardev_rs = rust.bindgen(
|
||||
args: bindgen_args_common + bindgen_args_data['chardev-sys'].split(),
|
||||
kwargs: bindgen_kwargs)
|
||||
_chardev_sys_rs = static_library(
|
||||
'chardev_sys',
|
||||
structured_sources(['lib.rs', _bindgen_chardev_rs]),
|
||||
override_options: ['rust_std=2021', 'build.rust_std=2021'],
|
||||
rust_abi: 'rust',
|
||||
dependencies: [glib_sys_rs, common_rs, qom_sys_rs, util_sys_rs],
|
||||
)
|
||||
|
||||
chardev_sys_rs = declare_dependency(link_with: [_chardev_sys_rs])
|
||||
12
rust/bindings/chardev-sys/wrapper.h
Normal file
12
rust/bindings/chardev-sys/wrapper.h
Normal file
@@ -0,0 +1,12 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/*
|
||||
* This header file is meant to be used as input to the `bindgen` application
|
||||
* in order to generate C FFI compatible Rust bindings.
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
|
||||
#include "chardev/char.h"
|
||||
#include "chardev/char-fe.h"
|
||||
#include "chardev/char-serial.h"
|
||||
164
rust/bindings/generate_bindgen_args.py
Normal file
164
rust/bindings/generate_bindgen_args.py
Normal file
@@ -0,0 +1,164 @@
|
||||
#!/usr/bin/env python3
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
"""
|
||||
Generate bindgen arguments from Cargo.toml metadata for QEMU's Rust FFI bindings.
|
||||
|
||||
Author: Paolo Bonzini <pbonzini@redhat.com>
|
||||
|
||||
Copyright (C) 2025 Red Hat, Inc.
|
||||
|
||||
This script processes Cargo.toml file for QEMU's bindings crates (util-sys,
|
||||
chardev-sys, qom-sys, etc.); it generates bindgen command lines that allow
|
||||
easy customization and that export the right headers in each bindings crate.
|
||||
|
||||
For detailed information, see docs/devel/rust.rst.
|
||||
"""
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import argparse
|
||||
from pathlib import Path
|
||||
from dataclasses import dataclass
|
||||
from typing import Iterable, List, Dict, Any
|
||||
|
||||
try:
|
||||
import tomllib
|
||||
except ImportError:
|
||||
import tomli as tomllib # type: ignore
|
||||
|
||||
INCLUDE_RE = re.compile(r'^#include\s+"([^"]+)"')
|
||||
OPTIONS = [
|
||||
"bitfield-enum",
|
||||
"newtype-enum",
|
||||
"newtype-global-enum",
|
||||
"rustified-enum",
|
||||
"rustified-non-exhaustive-enum",
|
||||
"constified-enum",
|
||||
"constified-enum-module",
|
||||
"normal-alias",
|
||||
"new-type-alias",
|
||||
"new-type-alias-deref",
|
||||
"bindgen-wrapper-union",
|
||||
"manually-drop-union",
|
||||
"blocklist-type",
|
||||
"blocklist-function",
|
||||
"blocklist-item",
|
||||
"blocklist-file",
|
||||
"blocklist-var",
|
||||
"opaque-type",
|
||||
"no-partialeq",
|
||||
"no-copy",
|
||||
"no-debug",
|
||||
"no-default",
|
||||
"no-hash",
|
||||
"must-use-type",
|
||||
"with-derive-custom",
|
||||
"with-derive-custom-struct",
|
||||
"with-derive-custom-enum",
|
||||
"with-derive-custom-union",
|
||||
"with-attribute-custom",
|
||||
"with-attribute-custom-struct",
|
||||
"with-attribute-custom-enum",
|
||||
"with-attribute-custom-union",
|
||||
]
|
||||
|
||||
|
||||
@dataclass
|
||||
class BindgenInfo:
|
||||
cmd_args: List[str]
|
||||
inputs: List[str]
|
||||
|
||||
|
||||
def extract_includes(lines: Iterable[str]) -> List[str]:
|
||||
"""Extract #include directives from a file."""
|
||||
includes: List[str] = []
|
||||
for line in lines:
|
||||
match = INCLUDE_RE.match(line.strip())
|
||||
if match:
|
||||
includes.append(match.group(1))
|
||||
return includes
|
||||
|
||||
|
||||
def build_bindgen_args(metadata: Dict[str, Any]) -> List[str]:
|
||||
"""Build command line arguments from [package.metadata.bindgen]."""
|
||||
args: List[str] = []
|
||||
for key, values in metadata.items():
|
||||
if key in OPTIONS:
|
||||
flag = f"--{key}"
|
||||
assert isinstance(values, list)
|
||||
for value in values:
|
||||
args.append(flag)
|
||||
args.append(value)
|
||||
|
||||
return args
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Generate bindgen arguments from Cargo.toml metadata"
|
||||
)
|
||||
parser.add_argument(
|
||||
"directories", nargs="+", help="Directories containing Cargo.toml files"
|
||||
)
|
||||
parser.add_argument(
|
||||
"-I",
|
||||
"--include-root",
|
||||
default=None,
|
||||
help="Base path for --allowlist-file/--blocklist-file",
|
||||
)
|
||||
parser.add_argument("--source-dir", default=os.getcwd(), help="Source directory")
|
||||
parser.add_argument("-o", "--output", required=True, help="Output file")
|
||||
parser.add_argument("--dep-file", help="Dependency file to write")
|
||||
args = parser.parse_args()
|
||||
|
||||
prev_allowlist_files: Dict[str, object] = {}
|
||||
bindgen_infos: Dict[str, BindgenInfo] = {}
|
||||
|
||||
os.chdir(args.source_dir)
|
||||
include_root = args.include_root or args.source_dir
|
||||
for directory in args.directories:
|
||||
cargo_path = Path(directory) / "Cargo.toml"
|
||||
inputs = [str(Path(args.source_dir) / cargo_path)]
|
||||
|
||||
with open(cargo_path, "rb") as f:
|
||||
cargo_toml = tomllib.load(f)
|
||||
|
||||
metadata = cargo_toml.get("package", {}).get("metadata", {}).get("bindgen", {})
|
||||
input_file = Path(directory) / metadata["header"]
|
||||
inputs.append(str(Path(args.source_dir) / input_file))
|
||||
|
||||
cmd_args = build_bindgen_args(metadata)
|
||||
|
||||
# Each include file is allowed for this file and blocked in the
|
||||
# next ones
|
||||
for blocklist_path in prev_allowlist_files:
|
||||
cmd_args.extend(["--blocklist-file", blocklist_path])
|
||||
with open(input_file, "r", encoding="utf-8", errors="ignore") as f:
|
||||
includes = extract_includes(f)
|
||||
for allowlist_file in includes + metadata.get("additional-files", []):
|
||||
allowlist_path = Path(include_root) / allowlist_file
|
||||
cmd_args.extend(["--allowlist-file", str(allowlist_path)])
|
||||
prev_allowlist_files.setdefault(str(allowlist_path), True)
|
||||
|
||||
bindgen_infos[directory] = BindgenInfo(cmd_args=cmd_args, inputs=inputs)
|
||||
|
||||
# now write the output
|
||||
with open(args.output, "w") as f:
|
||||
for directory, info in bindgen_infos.items():
|
||||
args_sh = " ".join(info.cmd_args)
|
||||
f.write(f"{directory}={args_sh}\n")
|
||||
|
||||
if args.dep_file:
|
||||
with open(args.dep_file, "w") as f:
|
||||
deps: List[str] = []
|
||||
for info in bindgen_infos.values():
|
||||
deps += info.inputs
|
||||
f.write(f"{os.path.basename(args.output)}: {' '.join(deps)}\n")
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
32
rust/bindings/hwcore-sys/Cargo.toml
Normal file
32
rust/bindings/hwcore-sys/Cargo.toml
Normal file
@@ -0,0 +1,32 @@
|
||||
[package]
|
||||
name = "hwcore-sys"
|
||||
version = "0.1.0"
|
||||
description = "Rust sys bindings for QEMU/hwcore"
|
||||
publish = false
|
||||
|
||||
authors.workspace = true
|
||||
edition.workspace = true
|
||||
homepage.workspace = true
|
||||
license.workspace = true
|
||||
repository.workspace = true
|
||||
rust-version.workspace = true
|
||||
|
||||
[lib]
|
||||
path = "lib.rs"
|
||||
|
||||
[dependencies]
|
||||
glib-sys = { workspace = true }
|
||||
common = { path = "../../common" }
|
||||
chardev-sys = { path = "../chardev-sys" }
|
||||
qom-sys = { path = "../qom-sys" }
|
||||
migration-sys = { path = "../migration-sys" }
|
||||
util-sys = { path = "../util-sys" }
|
||||
system-sys = { path = "../system-sys" }
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[package.metadata.bindgen]
|
||||
header = "wrapper.h"
|
||||
rustified-enum = ["DeviceCategory", "GpioPolarity", "MachineInitPhase", "ResetType"]
|
||||
bitfield-enum = ["ClockEvent"]
|
||||
1
rust/bindings/hwcore-sys/build.rs
Symbolic link
1
rust/bindings/hwcore-sys/build.rs
Symbolic link
@@ -0,0 +1 @@
|
||||
../build.rs
|
||||
@@ -18,13 +18,15 @@
|
||||
clippy::too_many_arguments
|
||||
)]
|
||||
|
||||
use chardev::bindings::Chardev;
|
||||
use chardev_sys::Chardev;
|
||||
use common::Zeroable;
|
||||
use glib_sys::{GHashTable, GHashTableIter, GList, GPtrArray, GSList};
|
||||
use migration::bindings::VMStateDescription;
|
||||
use qom::bindings::ObjectClass;
|
||||
use system::bindings::MemoryRegion;
|
||||
use util::bindings::Error;
|
||||
use glib_sys::GSList;
|
||||
use migration_sys::VMStateDescription;
|
||||
use qom_sys::{
|
||||
InterfaceClass, Object, ObjectClass, ObjectProperty, ObjectPropertyAccessor,
|
||||
ObjectPropertyRelease,
|
||||
};
|
||||
use util_sys::{Error, QDict, QList};
|
||||
|
||||
#[cfg(MESON)]
|
||||
include!("bindings.inc.rs");
|
||||
@@ -35,8 +37,5 @@ include!(concat!(env!("OUT_DIR"), "/bindings.inc.rs"));
|
||||
unsafe impl Send for Property {}
|
||||
unsafe impl Sync for Property {}
|
||||
|
||||
unsafe impl Send for TypeInfo {}
|
||||
unsafe impl Sync for TypeInfo {}
|
||||
|
||||
unsafe impl Zeroable for Property__bindgen_ty_1 {}
|
||||
unsafe impl Zeroable for Property {}
|
||||
12
rust/bindings/hwcore-sys/meson.build
Normal file
12
rust/bindings/hwcore-sys/meson.build
Normal file
@@ -0,0 +1,12 @@
|
||||
_bindgen_hwcore_rs = rust.bindgen(
|
||||
args: bindgen_args_common + bindgen_args_data['hwcore-sys'].split(),
|
||||
kwargs: bindgen_kwargs)
|
||||
_hwcore_sys_rs = static_library(
|
||||
'hwcore_sys',
|
||||
structured_sources(['lib.rs', _bindgen_hwcore_rs]),
|
||||
override_options: ['rust_std=2021', 'build.rust_std=2021'],
|
||||
rust_abi: 'rust',
|
||||
dependencies: [common_rs, glib_sys_rs, qom_sys_rs, util_sys_rs, migration_sys_rs, chardev_sys_rs],
|
||||
)
|
||||
|
||||
hwcore_sys_rs = declare_dependency(link_with: [_hwcore_sys_rs])
|
||||
30
rust/bindings/hwcore-sys/wrapper.h
Normal file
30
rust/bindings/hwcore-sys/wrapper.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/*
|
||||
* This header file is meant to be used as input to the `bindgen` application
|
||||
* in order to generate C FFI compatible Rust bindings.
|
||||
*/
|
||||
|
||||
/*
|
||||
* We block include/qemu/typedefs.h from bindgen, add here symbols
|
||||
* that are needed as opaque types by other functions.
|
||||
*/
|
||||
typedef struct Clock Clock;
|
||||
typedef struct DeviceState DeviceState;
|
||||
typedef struct IRQState *qemu_irq;
|
||||
typedef void (*qemu_irq_handler)(void *opaque, int n, int level);
|
||||
|
||||
/* Once bindings exist, these could move to a different *-sys crate. */
|
||||
typedef struct BlockBackend BlockBackend;
|
||||
typedef struct Monitor Monitor;
|
||||
typedef struct NetClientState NetClientState;
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
|
||||
#include "hw/core/clock.h"
|
||||
#include "hw/core/irq.h"
|
||||
#include "hw/core/qdev-clock.h"
|
||||
#include "hw/core/qdev.h"
|
||||
#include "hw/core/qdev-properties-system.h"
|
||||
#include "hw/core/qdev-properties.h"
|
||||
#include "hw/core/resettable.h"
|
||||
37
rust/bindings/meson.build
Normal file
37
rust/bindings/meson.build
Normal file
@@ -0,0 +1,37 @@
|
||||
# Generate bindgen arguments from Cargo.toml metadata
|
||||
# Sort these in dependency order, same as the subdir()
|
||||
# invocations below.
|
||||
bindgen_dirs = [
|
||||
'util-sys',
|
||||
'migration-sys',
|
||||
'qom-sys',
|
||||
'chardev-sys',
|
||||
'hwcore-sys',
|
||||
'system-sys',
|
||||
]
|
||||
bindgen_args_file = configure_file(
|
||||
command: [files('generate_bindgen_args.py'),
|
||||
'-I', meson.project_source_root() / 'include',
|
||||
'--source-dir', meson.current_source_dir(),
|
||||
'-o', '@OUTPUT@', '--dep-file', '@DEPFILE@'] + bindgen_dirs,
|
||||
output: 'bindgen_args.mak',
|
||||
depfile: 'bindgen_args.d'
|
||||
)
|
||||
|
||||
# now generate all bindgen files
|
||||
bindgen_args_data = keyval.load(bindgen_args_file)
|
||||
bindgen_kwargs = {
|
||||
'input': 'wrapper.h',
|
||||
'dependencies': common_ss.all_dependencies(),
|
||||
'output': 'bindings.inc.rs',
|
||||
'include_directories': bindings_incdir,
|
||||
'bindgen_version': ['>=0.60.0'],
|
||||
'c_args': bindgen_c_args,
|
||||
}
|
||||
|
||||
subdir('util-sys')
|
||||
subdir('migration-sys')
|
||||
subdir('qom-sys')
|
||||
subdir('chardev-sys')
|
||||
subdir('hwcore-sys')
|
||||
subdir('system-sys')
|
||||
28
rust/bindings/migration-sys/Cargo.toml
Normal file
28
rust/bindings/migration-sys/Cargo.toml
Normal file
@@ -0,0 +1,28 @@
|
||||
[package]
|
||||
name = "migration-sys"
|
||||
version = "0.1.0"
|
||||
description = "Rust sys bindings for QEMU/migration"
|
||||
publish = false
|
||||
|
||||
authors.workspace = true
|
||||
edition.workspace = true
|
||||
homepage.workspace = true
|
||||
license.workspace = true
|
||||
repository.workspace = true
|
||||
rust-version.workspace = true
|
||||
|
||||
[lib]
|
||||
path = "lib.rs"
|
||||
|
||||
[dependencies]
|
||||
glib-sys = { workspace = true }
|
||||
common = { path = "../../common" }
|
||||
util-sys = { path = "../util-sys" }
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[package.metadata.bindgen]
|
||||
header = "wrapper.h"
|
||||
bitfield-enum = ["MigrationPolicy", "MigrationPriority", "VMStateFlags"]
|
||||
blocklist-function = ["vmstate_register_ram", "vmstate_register_ram_global", "vmstate_unregister_ram"]
|
||||
1
rust/bindings/migration-sys/build.rs
Symbolic link
1
rust/bindings/migration-sys/build.rs
Symbolic link
@@ -0,0 +1 @@
|
||||
../build.rs
|
||||
125
rust/bindings/migration-sys/lib.rs
Normal file
125
rust/bindings/migration-sys/lib.rs
Normal file
@@ -0,0 +1,125 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#![allow(
|
||||
dead_code,
|
||||
improper_ctypes_definitions,
|
||||
improper_ctypes,
|
||||
non_camel_case_types,
|
||||
non_snake_case,
|
||||
non_upper_case_globals,
|
||||
unnecessary_transmutes,
|
||||
unsafe_op_in_unsafe_fn,
|
||||
clippy::pedantic,
|
||||
clippy::restriction,
|
||||
clippy::style,
|
||||
clippy::missing_const_for_fn,
|
||||
clippy::ptr_offset_with_cast,
|
||||
clippy::useless_transmute,
|
||||
clippy::missing_safety_doc,
|
||||
clippy::too_many_arguments
|
||||
)]
|
||||
|
||||
use common::Zeroable;
|
||||
use util_sys::{Error, JSONWriter, QEMUFile};
|
||||
|
||||
#[cfg(MESON)]
|
||||
include!("bindings.inc.rs");
|
||||
|
||||
#[cfg(not(MESON))]
|
||||
include!(concat!(env!("OUT_DIR"), "/bindings.inc.rs"));
|
||||
|
||||
unsafe impl Send for VMStateDescription {}
|
||||
unsafe impl Sync for VMStateDescription {}
|
||||
|
||||
unsafe impl Send for VMStateField {}
|
||||
unsafe impl Sync for VMStateField {}
|
||||
|
||||
unsafe impl Send for VMStateInfo {}
|
||||
unsafe impl Sync for VMStateInfo {}
|
||||
|
||||
// bindgen does not derive Default here
|
||||
#[allow(clippy::derivable_impls)]
|
||||
impl Default for VMStateFlags {
|
||||
fn default() -> Self {
|
||||
Self(0)
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Zeroable for VMStateFlags {}
|
||||
unsafe impl Zeroable for VMStateField {}
|
||||
unsafe impl Zeroable for VMStateDescription {}
|
||||
|
||||
// The following higher-level helpers could be in "migration"
|
||||
// crate when Rust has const trait impl.
|
||||
|
||||
pub trait VMStateFlagsExt {
|
||||
const VMS_VARRAY_FLAGS: VMStateFlags;
|
||||
}
|
||||
|
||||
impl VMStateFlagsExt for VMStateFlags {
|
||||
const VMS_VARRAY_FLAGS: VMStateFlags = VMStateFlags(
|
||||
VMStateFlags::VMS_VARRAY_INT32.0
|
||||
| VMStateFlags::VMS_VARRAY_UINT8.0
|
||||
| VMStateFlags::VMS_VARRAY_UINT16.0
|
||||
| VMStateFlags::VMS_VARRAY_UINT32.0,
|
||||
);
|
||||
}
|
||||
|
||||
// Add a couple builder-style methods to VMStateField, allowing
|
||||
// easy derivation of VMStateField constants from other types.
|
||||
impl VMStateField {
|
||||
#[must_use]
|
||||
pub const fn with_version_id(mut self, version_id: i32) -> Self {
|
||||
assert!(version_id >= 0);
|
||||
self.version_id = version_id;
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn with_array_flag(mut self, num: usize) -> Self {
|
||||
assert!(num <= 0x7FFF_FFFFusize);
|
||||
assert!((self.flags.0 & VMStateFlags::VMS_ARRAY.0) == 0);
|
||||
assert!((self.flags.0 & VMStateFlags::VMS_VARRAY_FLAGS.0) == 0);
|
||||
if (self.flags.0 & VMStateFlags::VMS_POINTER.0) != 0 {
|
||||
self.flags = VMStateFlags(self.flags.0 & !VMStateFlags::VMS_POINTER.0);
|
||||
self.flags = VMStateFlags(self.flags.0 | VMStateFlags::VMS_ARRAY_OF_POINTER.0);
|
||||
// VMS_ARRAY_OF_POINTER flag stores the size of pointer.
|
||||
// FIXME: *const, *mut, NonNull and Box<> have the same size as usize.
|
||||
// Resize if more smart pointers are supported.
|
||||
self.size = std::mem::size_of::<usize>();
|
||||
}
|
||||
self.flags = VMStateFlags(self.flags.0 & !VMStateFlags::VMS_SINGLE.0);
|
||||
self.flags = VMStateFlags(self.flags.0 | VMStateFlags::VMS_ARRAY.0);
|
||||
self.num = num as i32;
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn with_pointer_flag(mut self) -> Self {
|
||||
assert!((self.flags.0 & VMStateFlags::VMS_POINTER.0) == 0);
|
||||
self.flags = VMStateFlags(self.flags.0 | VMStateFlags::VMS_POINTER.0);
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn with_varray_flag_unchecked(mut self, flag: VMStateFlags) -> Self {
|
||||
self.flags = VMStateFlags(self.flags.0 & !VMStateFlags::VMS_ARRAY.0);
|
||||
self.flags = VMStateFlags(self.flags.0 | flag.0);
|
||||
self.num = 0; // varray uses num_offset instead of num.
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
#[allow(unused_mut)]
|
||||
pub const fn with_varray_flag(mut self, flag: VMStateFlags) -> Self {
|
||||
assert!((self.flags.0 & VMStateFlags::VMS_ARRAY.0) != 0);
|
||||
self.with_varray_flag_unchecked(flag)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn with_varray_multiply(mut self, num: u32) -> Self {
|
||||
assert!(num <= 0x7FFF_FFFFu32);
|
||||
self.flags = VMStateFlags(self.flags.0 | VMStateFlags::VMS_MULTIPLY_ELEMENTS.0);
|
||||
self.num = num as i32;
|
||||
self
|
||||
}
|
||||
}
|
||||
12
rust/bindings/migration-sys/meson.build
Normal file
12
rust/bindings/migration-sys/meson.build
Normal file
@@ -0,0 +1,12 @@
|
||||
_bindgen_migration_rs = rust.bindgen(
|
||||
args: bindgen_args_common + bindgen_args_data['migration-sys'].split(),
|
||||
kwargs: bindgen_kwargs)
|
||||
_migration_sys_rs = static_library(
|
||||
'migration_sys',
|
||||
structured_sources(['lib.rs', _bindgen_migration_rs]),
|
||||
override_options: ['rust_std=2021', 'build.rust_std=2021'],
|
||||
rust_abi: 'rust',
|
||||
dependencies: [glib_sys_rs, common_rs, util_sys_rs],
|
||||
)
|
||||
|
||||
migration_sys_rs = declare_dependency(link_with: [_migration_sys_rs])
|
||||
10
rust/bindings/migration-sys/wrapper.h
Normal file
10
rust/bindings/migration-sys/wrapper.h
Normal file
@@ -0,0 +1,10 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/*
|
||||
* This header file is meant to be used as input to the `bindgen` application
|
||||
* in order to generate C FFI compatible Rust bindings.
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
|
||||
#include "migration/vmstate.h"
|
||||
25
rust/bindings/qom-sys/Cargo.toml
Normal file
25
rust/bindings/qom-sys/Cargo.toml
Normal file
@@ -0,0 +1,25 @@
|
||||
[package]
|
||||
name = "qom-sys"
|
||||
version = "0.1.0"
|
||||
description = "Rust sys bindings for QEMU/qom"
|
||||
publish = false
|
||||
|
||||
authors.workspace = true
|
||||
edition.workspace = true
|
||||
homepage.workspace = true
|
||||
license.workspace = true
|
||||
repository.workspace = true
|
||||
rust-version.workspace = true
|
||||
|
||||
[lib]
|
||||
path = "lib.rs"
|
||||
|
||||
[dependencies]
|
||||
glib-sys = { workspace = true }
|
||||
util-sys = { path = "../util-sys" }
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[package.metadata.bindgen]
|
||||
header = "wrapper.h"
|
||||
1
rust/bindings/qom-sys/build.rs
Symbolic link
1
rust/bindings/qom-sys/build.rs
Symbolic link
@@ -0,0 +1 @@
|
||||
../build.rs
|
||||
@@ -19,9 +19,13 @@
|
||||
)]
|
||||
|
||||
use glib_sys::{GHashTable, GHashTableIter, GPtrArray, GSList};
|
||||
use util_sys::{Error, QDict, QObject, Visitor};
|
||||
|
||||
#[cfg(MESON)]
|
||||
include!("bindings.inc.rs");
|
||||
|
||||
#[cfg(not(MESON))]
|
||||
include!(concat!(env!("OUT_DIR"), "/bindings.inc.rs"));
|
||||
|
||||
unsafe impl Send for TypeInfo {}
|
||||
unsafe impl Sync for TypeInfo {}
|
||||
12
rust/bindings/qom-sys/meson.build
Normal file
12
rust/bindings/qom-sys/meson.build
Normal file
@@ -0,0 +1,12 @@
|
||||
_bindgen_qom_rs = rust.bindgen(
|
||||
args: bindgen_args_common + bindgen_args_data['qom-sys'].split(),
|
||||
kwargs: bindgen_kwargs)
|
||||
_qom_sys_rs = static_library(
|
||||
'qom_sys',
|
||||
structured_sources(['lib.rs', _bindgen_qom_rs]),
|
||||
override_options: ['rust_std=2021', 'build.rust_std=2021'],
|
||||
rust_abi: 'rust',
|
||||
dependencies: [glib_sys_rs, util_sys_rs],
|
||||
)
|
||||
|
||||
qom_sys_rs = declare_dependency(link_with: [_qom_sys_rs])
|
||||
17
rust/bindings/qom-sys/wrapper.h
Normal file
17
rust/bindings/qom-sys/wrapper.h
Normal file
@@ -0,0 +1,17 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/*
|
||||
* This header file is meant to be used as input to the `bindgen` application
|
||||
* in order to generate C FFI compatible Rust bindings.
|
||||
*/
|
||||
|
||||
/*
|
||||
* We block include/qemu/typedefs.h from bindgen, add here symbols
|
||||
* that are needed as opaque types by other functions.
|
||||
*/
|
||||
typedef struct Object Object;
|
||||
typedef struct ObjectClass ObjectClass;
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
|
||||
#include "qom/object.h"
|
||||
30
rust/bindings/system-sys/Cargo.toml
Normal file
30
rust/bindings/system-sys/Cargo.toml
Normal file
@@ -0,0 +1,30 @@
|
||||
[package]
|
||||
name = "system-sys"
|
||||
version = "0.1.0"
|
||||
description = "Rust sys bindings for QEMU/system"
|
||||
publish = false
|
||||
|
||||
authors.workspace = true
|
||||
edition.workspace = true
|
||||
homepage.workspace = true
|
||||
license.workspace = true
|
||||
repository.workspace = true
|
||||
rust-version.workspace = true
|
||||
|
||||
[lib]
|
||||
path = "lib.rs"
|
||||
|
||||
[dependencies]
|
||||
glib-sys = { workspace = true }
|
||||
common = { path = "../../common" }
|
||||
migration-sys = { path = "../migration-sys" }
|
||||
util-sys = { path = "../util-sys" }
|
||||
qom-sys = { path = "../qom-sys" }
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[package.metadata.bindgen]
|
||||
header = "wrapper.h"
|
||||
rustified-enum = ["device_endian"]
|
||||
additional-files = ["system/memory.*"]
|
||||
1
rust/bindings/system-sys/build.rs
Symbolic link
1
rust/bindings/system-sys/build.rs
Symbolic link
@@ -0,0 +1 @@
|
||||
../build.rs
|
||||
@@ -19,7 +19,9 @@
|
||||
)]
|
||||
|
||||
use common::Zeroable;
|
||||
use glib_sys::{guint, GHashTable, GHashTableIter, GList, GPollFD, GPtrArray, GSList};
|
||||
use hwcore_sys::{qemu_irq, DeviceClass, DeviceState};
|
||||
use qom_sys::{InterfaceClass, Object, ObjectClass};
|
||||
use util_sys::{Error, EventNotifier, QEMUBH};
|
||||
|
||||
#[cfg(MESON)]
|
||||
include!("bindings.inc.rs");
|
||||
12
rust/bindings/system-sys/meson.build
Normal file
12
rust/bindings/system-sys/meson.build
Normal file
@@ -0,0 +1,12 @@
|
||||
_bindgen_system_rs = rust.bindgen(
|
||||
args: bindgen_args_common + bindgen_args_data['system-sys'].split(),
|
||||
kwargs: bindgen_kwargs)
|
||||
_system_sys_rs = static_library(
|
||||
'system_sys',
|
||||
structured_sources(['lib.rs', _bindgen_system_rs]),
|
||||
override_options: ['rust_std=2021', 'build.rust_std=2021'],
|
||||
rust_abi: 'rust',
|
||||
dependencies: [common_rs, glib_sys_rs, hwcore_sys_rs, migration_sys_rs, qom_sys_rs, util_sys_rs],
|
||||
)
|
||||
|
||||
system_sys_rs = declare_dependency(link_with: [_system_sys_rs])
|
||||
21
rust/bindings/system-sys/wrapper.h
Normal file
21
rust/bindings/system-sys/wrapper.h
Normal file
@@ -0,0 +1,21 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/*
|
||||
* This header file is meant to be used as input to the `bindgen` application
|
||||
* in order to generate C FFI compatible Rust bindings.
|
||||
*/
|
||||
|
||||
/*
|
||||
* We block include/qemu/typedefs.h from bindgen, add here symbols
|
||||
* that are needed as opaque types by other functions.
|
||||
*/
|
||||
typedef struct DirtyBitmapSnapshot DirtyBitmapSnapshot;
|
||||
typedef struct MemoryRegion MemoryRegion;
|
||||
typedef struct RAMBlock RAMBlock;
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
|
||||
#include "exec/hwaddr.h"
|
||||
#include "system/address-spaces.h"
|
||||
#include "system/memory.h"
|
||||
#include "hw/core/sysbus.h"
|
||||
25
rust/bindings/util-sys/Cargo.toml
Normal file
25
rust/bindings/util-sys/Cargo.toml
Normal file
@@ -0,0 +1,25 @@
|
||||
[package]
|
||||
name = "util-sys"
|
||||
version = "0.1.0"
|
||||
description = "Rust sys bindings for QEMU/util"
|
||||
publish = false
|
||||
|
||||
authors.workspace = true
|
||||
edition.workspace = true
|
||||
homepage.workspace = true
|
||||
license.workspace = true
|
||||
repository.workspace = true
|
||||
rust-version.workspace = true
|
||||
|
||||
[lib]
|
||||
path = "lib.rs"
|
||||
|
||||
[dependencies]
|
||||
glib-sys = { workspace = true }
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[package.metadata.bindgen]
|
||||
header = "wrapper.h"
|
||||
rustified-enum = ["module_init_type", "QEMUClockType"]
|
||||
1
rust/bindings/util-sys/build.rs
Symbolic link
1
rust/bindings/util-sys/build.rs
Symbolic link
@@ -0,0 +1 @@
|
||||
../build.rs
|
||||
@@ -18,7 +18,7 @@
|
||||
clippy::too_many_arguments
|
||||
)]
|
||||
|
||||
use glib_sys::{guint, GPollFD, GString};
|
||||
use glib_sys::{guint, GArray, GHashTable, GPollFD, GSList, GSource, GString};
|
||||
|
||||
#[cfg(MESON)]
|
||||
include!("bindings.inc.rs");
|
||||
12
rust/bindings/util-sys/meson.build
Normal file
12
rust/bindings/util-sys/meson.build
Normal file
@@ -0,0 +1,12 @@
|
||||
_bindgen_util_rs = rust.bindgen(
|
||||
args: bindgen_args_common + bindgen_args_data['util-sys'].split(),
|
||||
kwargs: bindgen_kwargs)
|
||||
_util_sys_rs = static_library(
|
||||
'util_sys',
|
||||
structured_sources(['lib.rs', _bindgen_util_rs]),
|
||||
override_options: ['rust_std=2021', 'build.rust_std=2021'],
|
||||
rust_abi: 'rust',
|
||||
dependencies: [glib_sys_rs],
|
||||
)
|
||||
|
||||
util_sys_rs = declare_dependency(link_with: [_util_sys_rs])
|
||||
39
rust/bindings/util-sys/wrapper.h
Normal file
39
rust/bindings/util-sys/wrapper.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/*
|
||||
* This header file is meant to be used as input to the `bindgen` application
|
||||
* in order to generate C FFI compatible Rust bindings.
|
||||
*/
|
||||
|
||||
/*
|
||||
* We block include/qemu/typedefs.h from bindgen, add here symbols
|
||||
* that are needed as opaque types by other functions.
|
||||
*/
|
||||
typedef struct QEMUBH QEMUBH;
|
||||
typedef struct QEMUFile QEMUFile;
|
||||
typedef struct QemuOpts QemuOpts;
|
||||
typedef struct JSONWriter JSONWriter;
|
||||
typedef struct Visitor Visitor;
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
|
||||
#include "qapi/error.h"
|
||||
#include "qapi/error-internal.h"
|
||||
#include "qemu/event_notifier.h"
|
||||
#include "qemu/main-loop.h"
|
||||
#include "qemu/aio.h"
|
||||
#include "qemu/log-for-trace.h"
|
||||
#include "qemu/log.h"
|
||||
#include "qemu/module.h"
|
||||
#include "qemu/option.h"
|
||||
#include "qemu/timer.h"
|
||||
#include "qapi/visitor.h"
|
||||
#include "qobject/qbool.h"
|
||||
#include "qobject/qdict.h"
|
||||
#include "qobject/qjson.h"
|
||||
#include "qobject/qlist.h"
|
||||
#include "qobject/qnull.h"
|
||||
#include "qobject/qnum.h"
|
||||
#include "qobject/qobject.h"
|
||||
#include "qobject/qstring.h"
|
||||
#include "qobject/json-writer.h"
|
||||
@@ -14,6 +14,7 @@ rust-version.workspace = true
|
||||
|
||||
[dependencies]
|
||||
glib-sys.workspace = true
|
||||
util-sys = { path = "../bindings/util-sys" }
|
||||
|
||||
[features]
|
||||
default = ["debug_cell"]
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
../util/build.rs
|
||||
@@ -6,37 +6,11 @@ if get_option('debug_mutex')
|
||||
_bql_cfg += ['--cfg', 'feature="debug_cell"']
|
||||
endif
|
||||
|
||||
#
|
||||
# TODO: Remove this comment when the clang/libclang mismatch issue is solved.
|
||||
#
|
||||
# Rust bindings generation with `bindgen` might fail in some cases where the
|
||||
# detected `libclang` does not match the expected `clang` version/target. In
|
||||
# this case you must pass the path to `clang` and `libclang` to your build
|
||||
# command invocation using the environment variables CLANG_PATH and
|
||||
# LIBCLANG_PATH
|
||||
_bql_bindings_inc_rs = rust.bindgen(
|
||||
input: 'wrapper.h',
|
||||
dependencies: common_ss.all_dependencies(),
|
||||
output: 'bindings.inc.rs',
|
||||
include_directories: bindings_incdir,
|
||||
bindgen_version: ['>=0.60.0'],
|
||||
args: bindgen_args_common,
|
||||
c_args: bindgen_c_args,
|
||||
)
|
||||
|
||||
_bql_rs = static_library(
|
||||
'bql',
|
||||
structured_sources(
|
||||
[
|
||||
'src/lib.rs',
|
||||
'src/bindings.rs',
|
||||
'src/cell.rs',
|
||||
'src/prelude.rs',
|
||||
],
|
||||
{'.': _bql_bindings_inc_rs}
|
||||
),
|
||||
'src/lib.rs',
|
||||
rust_args: _bql_cfg,
|
||||
dependencies: [glib_sys_rs],
|
||||
dependencies: [glib_sys_rs, util_sys_rs],
|
||||
)
|
||||
|
||||
bql_rs = declare_dependency(link_with: [_bql_rs],
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#![allow(
|
||||
dead_code,
|
||||
improper_ctypes_definitions,
|
||||
improper_ctypes,
|
||||
non_camel_case_types,
|
||||
non_snake_case,
|
||||
non_upper_case_globals,
|
||||
unnecessary_transmutes,
|
||||
unsafe_op_in_unsafe_fn,
|
||||
clippy::pedantic,
|
||||
clippy::restriction,
|
||||
clippy::style,
|
||||
clippy::missing_const_for_fn,
|
||||
clippy::ptr_offset_with_cast,
|
||||
clippy::useless_transmute,
|
||||
clippy::missing_safety_doc,
|
||||
clippy::too_many_arguments
|
||||
)]
|
||||
|
||||
use glib_sys::{guint, GArray, GHashTable, GHashTableIter, GPollFD, GPtrArray, GSList, GSource};
|
||||
|
||||
#[cfg(MESON)]
|
||||
include!("bindings.inc.rs");
|
||||
|
||||
#[cfg(not(MESON))]
|
||||
include!(concat!(env!("OUT_DIR"), "/bindings.inc.rs"));
|
||||
@@ -1,7 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
mod bindings;
|
||||
use bindings::{bql_block_unlock, bql_locked, rust_bql_mock_lock};
|
||||
use util_sys::{bql_block_unlock, bql_locked, rust_bql_mock_lock};
|
||||
|
||||
mod cell;
|
||||
pub use cell::*;
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/*
|
||||
* This header file is meant to be used as input to the `bindgen` application
|
||||
* in order to generate C FFI compatible Rust bindings.
|
||||
*/
|
||||
|
||||
#ifndef __CLANG_STDATOMIC_H
|
||||
#define __CLANG_STDATOMIC_H
|
||||
/*
|
||||
* Fix potential missing stdatomic.h error in case bindgen does not insert the
|
||||
* correct libclang header paths on its own. We do not use stdatomic.h symbols
|
||||
* in QEMU code, so it's fine to declare dummy types instead.
|
||||
*/
|
||||
typedef enum memory_order {
|
||||
memory_order_relaxed,
|
||||
memory_order_consume,
|
||||
memory_order_acquire,
|
||||
memory_order_release,
|
||||
memory_order_acq_rel,
|
||||
memory_order_seq_cst,
|
||||
} memory_order;
|
||||
#endif /* __CLANG_STDATOMIC_H */
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
|
||||
#include "qemu/main-loop.h"
|
||||
@@ -14,6 +14,7 @@ rust-version.workspace = true
|
||||
|
||||
[dependencies]
|
||||
glib-sys = { workspace = true }
|
||||
chardev-sys = { path = "../bindings/chardev-sys" }
|
||||
common = { path = "../common" }
|
||||
bql = { path = "../bql" }
|
||||
migration = { path = "../migration" }
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
../util/build.rs
|
||||
@@ -1,41 +1,8 @@
|
||||
c_enums = [
|
||||
'QEMUChrEvent',
|
||||
]
|
||||
_chardev_bindgen_args = []
|
||||
foreach enum : c_enums
|
||||
_chardev_bindgen_args += ['--rustified-enum', enum]
|
||||
endforeach
|
||||
|
||||
# TODO: Remove this comment when the clang/libclang mismatch issue is solved.
|
||||
#
|
||||
# Rust bindings generation with `bindgen` might fail in some cases where the
|
||||
# detected `libclang` does not match the expected `clang` version/target. In
|
||||
# this case you must pass the path to `clang` and `libclang` to your build
|
||||
# command invocation using the environment variables CLANG_PATH and
|
||||
# LIBCLANG_PATH
|
||||
_chardev_bindings_inc_rs = rust.bindgen(
|
||||
input: 'wrapper.h',
|
||||
dependencies: common_ss.all_dependencies(),
|
||||
output: 'bindings.inc.rs',
|
||||
include_directories: bindings_incdir,
|
||||
bindgen_version: ['>=0.60.0'],
|
||||
args: bindgen_args_common + _chardev_bindgen_args,
|
||||
c_args: bindgen_c_args,
|
||||
)
|
||||
|
||||
_chardev_rs = static_library(
|
||||
'chardev',
|
||||
structured_sources(
|
||||
[
|
||||
'src/lib.rs',
|
||||
'src/bindings.rs',
|
||||
'src/chardev.rs',
|
||||
'src/prelude.rs',
|
||||
],
|
||||
{'.': _chardev_bindings_inc_rs}
|
||||
),
|
||||
'src/lib.rs',
|
||||
link_with: [_bql_rs, _migration_rs, _qom_rs, _util_rs],
|
||||
dependencies: [glib_sys_rs, common_rs, qemu_macros],
|
||||
dependencies: [glib_sys_rs, common_rs, qemu_macros, chardev_sys_rs],
|
||||
)
|
||||
|
||||
chardev_rs = declare_dependency(link_with: [_chardev_rs], dependencies: [chardev, qemuutil])
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
pub mod bindings;
|
||||
pub use chardev_sys as bindings;
|
||||
|
||||
mod chardev;
|
||||
pub use chardev::*;
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/*
|
||||
* This header file is meant to be used as input to the `bindgen` application
|
||||
* in order to generate C FFI compatible Rust bindings.
|
||||
*/
|
||||
|
||||
#ifndef __CLANG_STDATOMIC_H
|
||||
#define __CLANG_STDATOMIC_H
|
||||
/*
|
||||
* Fix potential missing stdatomic.h error in case bindgen does not insert the
|
||||
* correct libclang header paths on its own. We do not use stdatomic.h symbols
|
||||
* in QEMU code, so it's fine to declare dummy types instead.
|
||||
*/
|
||||
typedef enum memory_order {
|
||||
memory_order_relaxed,
|
||||
memory_order_consume,
|
||||
memory_order_acquire,
|
||||
memory_order_release,
|
||||
memory_order_acq_rel,
|
||||
memory_order_seq_cst,
|
||||
} memory_order;
|
||||
#endif /* __CLANG_STDATOMIC_H */
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
|
||||
#include "chardev/char-fe.h"
|
||||
#include "chardev/char-serial.h"
|
||||
@@ -1 +1 @@
|
||||
../../../util/build.rs
|
||||
../../../bindings/build.rs
|
||||
@@ -1,18 +1,11 @@
|
||||
# TODO: Remove this comment when the clang/libclang mismatch issue is solved.
|
||||
#
|
||||
# Rust bindings generation with `bindgen` might fail in some cases where the
|
||||
# detected `libclang` does not match the expected `clang` version/target. In
|
||||
# this case you must pass the path to `clang` and `libclang` to your build
|
||||
# command invocation using the environment variables CLANG_PATH and
|
||||
# LIBCLANG_PATH
|
||||
_libpl011_bindings_inc_rs = rust.bindgen(
|
||||
input: 'wrapper.h',
|
||||
dependencies: common_ss.all_dependencies(),
|
||||
output: 'bindings.inc.rs',
|
||||
include_directories: bindings_incdir,
|
||||
bindgen_version: ['>=0.60.0'],
|
||||
args: bindgen_args_common,
|
||||
c_args: bindgen_c_args,
|
||||
args: bindgen_args_common + [
|
||||
'--allowlist-file', meson.project_source_root() / 'include/hw/char/pl011.h',
|
||||
'--blocklist-file',
|
||||
meson.project_source_root() /
|
||||
'include/(block\|chardev/|exec/|hw/core/|qemu/|qom/|system/).*',
|
||||
],
|
||||
kwargs: bindgen_kwargs,
|
||||
)
|
||||
|
||||
_libpl011_rs = static_library(
|
||||
|
||||
@@ -20,10 +20,9 @@
|
||||
|
||||
//! `bindgen`-generated declarations.
|
||||
|
||||
use glib_sys::{
|
||||
gboolean, guint, GArray, GHashTable, GHashTableIter, GIOCondition, GList, GMainContext,
|
||||
GPollFD, GPtrArray, GSList, GSource, GSourceFunc,
|
||||
};
|
||||
use chardev::bindings::{CharFrontend, Chardev};
|
||||
use hwcore::bindings::{qemu_irq, Clock, DeviceState};
|
||||
use system::bindings::{hwaddr, MemoryRegion, SysBusDevice};
|
||||
|
||||
#[cfg(MESON)]
|
||||
include!("bindings.inc.rs");
|
||||
|
||||
@@ -14,6 +14,7 @@ rust-version.workspace = true
|
||||
|
||||
[dependencies]
|
||||
glib-sys.workspace = true
|
||||
hwcore-sys = { path = "../../bindings/hwcore-sys" }
|
||||
qemu_macros = { path = "../../qemu-macros" }
|
||||
common = { path = "../../common" }
|
||||
bql = { path = "../../bql" }
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
../../util/build.rs
|
||||
@@ -1,66 +1,10 @@
|
||||
_hwcore_bindgen_args = []
|
||||
c_enums = [
|
||||
'DeviceCategory',
|
||||
'GpioPolarity',
|
||||
'MachineInitPhase',
|
||||
'ResetType',
|
||||
]
|
||||
foreach enum : c_enums
|
||||
_hwcore_bindgen_args += ['--rustified-enum', enum]
|
||||
endforeach
|
||||
|
||||
blocked_type = [
|
||||
'Chardev',
|
||||
'Error',
|
||||
'ObjectClass',
|
||||
'MemoryRegion',
|
||||
'VMStateDescription',
|
||||
]
|
||||
foreach type: blocked_type
|
||||
_hwcore_bindgen_args += ['--blocklist-type', type]
|
||||
endforeach
|
||||
|
||||
c_bitfields = [
|
||||
'ClockEvent',
|
||||
]
|
||||
foreach enum : c_bitfields
|
||||
_hwcore_bindgen_args += ['--bitfield-enum', enum]
|
||||
endforeach
|
||||
|
||||
# TODO: Remove this comment when the clang/libclang mismatch issue is solved.
|
||||
#
|
||||
# Rust bindings generation with `bindgen` might fail in some cases where the
|
||||
# detected `libclang` does not match the expected `clang` version/target. In
|
||||
# this case you must pass the path to `clang` and `libclang` to your build
|
||||
# command invocation using the environment variables CLANG_PATH and
|
||||
# LIBCLANG_PATH
|
||||
_hwcore_bindings_inc_rs = rust.bindgen(
|
||||
input: 'wrapper.h',
|
||||
dependencies: common_ss.all_dependencies(),
|
||||
output: 'bindings.inc.rs',
|
||||
include_directories: bindings_incdir,
|
||||
bindgen_version: ['>=0.60.0'],
|
||||
args: bindgen_args_common + _hwcore_bindgen_args,
|
||||
c_args: bindgen_c_args,
|
||||
)
|
||||
|
||||
_hwcore_rs = static_library(
|
||||
'hwcore',
|
||||
structured_sources(
|
||||
[
|
||||
'src/lib.rs',
|
||||
'src/bindings.rs',
|
||||
'src/irq.rs',
|
||||
'src/prelude.rs',
|
||||
'src/qdev.rs',
|
||||
'src/sysbus.rs',
|
||||
],
|
||||
{'.': _hwcore_bindings_inc_rs}
|
||||
),
|
||||
'src/lib.rs',
|
||||
override_options: ['rust_std=2021', 'build.rust_std=2021'],
|
||||
rust_abi: 'rust',
|
||||
link_with: [_bql_rs, _chardev_rs, _migration_rs, _qom_rs, _system_rs, _util_rs],
|
||||
dependencies: [glib_sys_rs, qemu_macros, common_rs],
|
||||
dependencies: [glib_sys_rs, qemu_macros, common_rs, hwcore_sys_rs],
|
||||
)
|
||||
|
||||
hwcore_rs = declare_dependency(link_with: [_hwcore_rs],
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
pub use hwcore_sys as bindings;
|
||||
pub use qemu_macros::Device;
|
||||
pub use qom;
|
||||
|
||||
pub mod bindings;
|
||||
|
||||
mod irq;
|
||||
pub use irq::*;
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ pub trait ResettablePhasesImpl {
|
||||
/// can be downcasted to type `T`. We also expect the device is
|
||||
/// readable/writeable from one thread at any time.
|
||||
unsafe extern "C" fn rust_resettable_enter_fn<T: ResettablePhasesImpl>(
|
||||
obj: *mut bindings::Object,
|
||||
obj: *mut qom::bindings::Object,
|
||||
typ: ResetType,
|
||||
) {
|
||||
let state = NonNull::new(obj).unwrap().cast::<T>();
|
||||
@@ -79,7 +79,7 @@ unsafe extern "C" fn rust_resettable_enter_fn<T: ResettablePhasesImpl>(
|
||||
/// can be downcasted to type `T`. We also expect the device is
|
||||
/// readable/writeable from one thread at any time.
|
||||
unsafe extern "C" fn rust_resettable_hold_fn<T: ResettablePhasesImpl>(
|
||||
obj: *mut bindings::Object,
|
||||
obj: *mut qom::bindings::Object,
|
||||
typ: ResetType,
|
||||
) {
|
||||
let state = NonNull::new(obj).unwrap().cast::<T>();
|
||||
@@ -92,7 +92,7 @@ unsafe extern "C" fn rust_resettable_hold_fn<T: ResettablePhasesImpl>(
|
||||
/// can be downcasted to type `T`. We also expect the device is
|
||||
/// readable/writeable from one thread at any time.
|
||||
unsafe extern "C" fn rust_resettable_exit_fn<T: ResettablePhasesImpl>(
|
||||
obj: *mut bindings::Object,
|
||||
obj: *mut qom::bindings::Object,
|
||||
typ: ResetType,
|
||||
) {
|
||||
let state = NonNull::new(obj).unwrap().cast::<T>();
|
||||
|
||||
@@ -6,22 +6,21 @@
|
||||
|
||||
use std::ffi::CStr;
|
||||
|
||||
pub use bindings::SysBusDeviceClass;
|
||||
use common::Opaque;
|
||||
use qom::prelude::*;
|
||||
use system::MemoryRegion;
|
||||
pub use system_sys::SysBusDeviceClass;
|
||||
use util::{Error, Result};
|
||||
|
||||
use crate::{
|
||||
bindings,
|
||||
irq::{IRQState, InterruptSource},
|
||||
qdev::{DeviceClassExt, DeviceImpl, DeviceState},
|
||||
};
|
||||
|
||||
/// A safe wrapper around [`bindings::SysBusDevice`].
|
||||
/// A safe wrapper around [`system_sys::SysBusDevice`].
|
||||
#[repr(transparent)]
|
||||
#[derive(Debug, common::Wrapper)]
|
||||
pub struct SysBusDevice(Opaque<bindings::SysBusDevice>);
|
||||
pub struct SysBusDevice(Opaque<system_sys::SysBusDevice>);
|
||||
|
||||
unsafe impl Send for SysBusDevice {}
|
||||
unsafe impl Sync for SysBusDevice {}
|
||||
@@ -29,7 +28,7 @@ unsafe impl Sync for SysBusDevice {}
|
||||
unsafe impl ObjectType for SysBusDevice {
|
||||
type Class = SysBusDeviceClass;
|
||||
const TYPE_NAME: &'static CStr =
|
||||
unsafe { CStr::from_bytes_with_nul_unchecked(bindings::TYPE_SYS_BUS_DEVICE) };
|
||||
unsafe { CStr::from_bytes_with_nul_unchecked(system_sys::TYPE_SYS_BUS_DEVICE) };
|
||||
}
|
||||
|
||||
qom_isa!(SysBusDevice: DeviceState, Object);
|
||||
@@ -62,7 +61,7 @@ where
|
||||
fn init_mmio(&self, iomem: &MemoryRegion) {
|
||||
assert!(bql::is_locked());
|
||||
unsafe {
|
||||
bindings::sysbus_init_mmio(self.upcast().as_mut_ptr(), iomem.as_mut_ptr());
|
||||
system_sys::sysbus_init_mmio(self.upcast().as_mut_ptr(), iomem.as_mut_ptr());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +72,7 @@ where
|
||||
fn init_irq(&self, irq: &InterruptSource) {
|
||||
assert!(bql::is_locked());
|
||||
unsafe {
|
||||
bindings::sysbus_init_irq(self.upcast().as_mut_ptr(), irq.as_ptr());
|
||||
system_sys::sysbus_init_irq(self.upcast().as_mut_ptr(), irq.as_ptr());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,7 +81,7 @@ where
|
||||
assert!(bql::is_locked());
|
||||
// SAFETY: the BQL ensures that no one else writes to sbd.mmio[], and
|
||||
// the SysBusDevice must be initialized to get an IsA<SysBusDevice>.
|
||||
let sbd = unsafe { &*self.upcast().as_ptr() };
|
||||
let sbd = unsafe { &*self.upcast().as_mut_ptr() };
|
||||
let id: usize = id.try_into().unwrap();
|
||||
if sbd.mmio[id].memory.is_null() {
|
||||
None
|
||||
@@ -96,7 +95,7 @@ where
|
||||
assert!(bql::is_locked());
|
||||
let id: i32 = id.try_into().unwrap();
|
||||
unsafe {
|
||||
bindings::sysbus_mmio_map(self.upcast().as_mut_ptr(), id, addr);
|
||||
system_sys::sysbus_mmio_map(self.upcast().as_mut_ptr(), id, addr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,7 +107,7 @@ where
|
||||
let id: i32 = id.try_into().unwrap();
|
||||
let irq: &IRQState = irq;
|
||||
unsafe {
|
||||
bindings::sysbus_connect_irq(self.upcast().as_mut_ptr(), id, irq.as_mut_ptr());
|
||||
system_sys::sysbus_connect_irq(self.upcast().as_mut_ptr(), id, irq.as_mut_ptr());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,7 +115,7 @@ where
|
||||
assert!(bql::is_locked());
|
||||
unsafe {
|
||||
Error::with_errp(|errp| {
|
||||
bindings::sysbus_realize(self.upcast().as_mut_ptr(), errp);
|
||||
system_sys::sysbus_realize(self.upcast().as_mut_ptr(), errp);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/*
|
||||
* This header file is meant to be used as input to the `bindgen` application
|
||||
* in order to generate C FFI compatible Rust bindings.
|
||||
*/
|
||||
|
||||
#ifndef __CLANG_STDATOMIC_H
|
||||
#define __CLANG_STDATOMIC_H
|
||||
/*
|
||||
* Fix potential missing stdatomic.h error in case bindgen does not insert the
|
||||
* correct libclang header paths on its own. We do not use stdatomic.h symbols
|
||||
* in QEMU code, so it's fine to declare dummy types instead.
|
||||
*/
|
||||
typedef enum memory_order {
|
||||
memory_order_relaxed,
|
||||
memory_order_consume,
|
||||
memory_order_acquire,
|
||||
memory_order_release,
|
||||
memory_order_acq_rel,
|
||||
memory_order_seq_cst,
|
||||
} memory_order;
|
||||
#endif /* __CLANG_STDATOMIC_H */
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
|
||||
#include "hw/core/sysbus.h"
|
||||
#include "hw/core/clock.h"
|
||||
#include "hw/core/qdev-clock.h"
|
||||
#include "hw/core/qdev-properties.h"
|
||||
#include "hw/core/qdev-properties-system.h"
|
||||
#include "hw/core/irq.h"
|
||||
@@ -35,6 +35,7 @@ genrs = []
|
||||
subdir('qemu-macros')
|
||||
|
||||
subdir('common')
|
||||
subdir('bindings')
|
||||
subdir('bits')
|
||||
|
||||
subdir('util')
|
||||
|
||||
@@ -17,6 +17,7 @@ bql = { path = "../bql" }
|
||||
common = { path = "../common" }
|
||||
qemu_macros = { path = "../qemu-macros" }
|
||||
util = { path = "../util" }
|
||||
migration-sys = { path = "../bindings/migration-sys" }
|
||||
glib-sys.workspace = true
|
||||
|
||||
[lints]
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
../util/build.rs
|
||||
@@ -1,44 +1,8 @@
|
||||
_migration_bindgen_args = []
|
||||
c_bitfields = [
|
||||
'MigrationPolicy',
|
||||
'MigrationPriority',
|
||||
'VMStateFlags',
|
||||
]
|
||||
foreach enum : c_bitfields
|
||||
_migration_bindgen_args += ['--bitfield-enum', enum]
|
||||
endforeach
|
||||
#
|
||||
# TODO: Remove this comment when the clang/libclang mismatch issue is solved.
|
||||
#
|
||||
# Rust bindings generation with `bindgen` might fail in some cases where the
|
||||
# detected `libclang` does not match the expected `clang` version/target. In
|
||||
# this case you must pass the path to `clang` and `libclang` to your build
|
||||
# command invocation using the environment variables CLANG_PATH and
|
||||
# LIBCLANG_PATH
|
||||
_migration_bindings_inc_rs = rust.bindgen(
|
||||
input: 'wrapper.h',
|
||||
dependencies: common_ss.all_dependencies(),
|
||||
output: 'bindings.inc.rs',
|
||||
include_directories: bindings_incdir,
|
||||
bindgen_version: ['>=0.60.0'],
|
||||
args: bindgen_args_common + _migration_bindgen_args,
|
||||
c_args: bindgen_c_args,
|
||||
)
|
||||
|
||||
_migration_rs = static_library(
|
||||
'migration',
|
||||
structured_sources(
|
||||
[
|
||||
'src/lib.rs',
|
||||
'src/bindings.rs',
|
||||
'src/migratable.rs',
|
||||
'src/prelude.rs',
|
||||
'src/vmstate.rs',
|
||||
],
|
||||
{'.' : _migration_bindings_inc_rs},
|
||||
),
|
||||
'src/lib.rs',
|
||||
link_with: [_util_rs, _bql_rs],
|
||||
dependencies: [common_rs, glib_sys_rs, qemu_macros],
|
||||
dependencies: [common_rs, glib_sys_rs, qemu_macros, migration_sys_rs],
|
||||
)
|
||||
|
||||
migration_rs = declare_dependency(link_with: [_migration_rs],
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#![allow(
|
||||
dead_code,
|
||||
improper_ctypes_definitions,
|
||||
improper_ctypes,
|
||||
non_camel_case_types,
|
||||
non_snake_case,
|
||||
non_upper_case_globals,
|
||||
unnecessary_transmutes,
|
||||
unsafe_op_in_unsafe_fn,
|
||||
clippy::pedantic,
|
||||
clippy::restriction,
|
||||
clippy::style,
|
||||
clippy::missing_const_for_fn,
|
||||
clippy::ptr_offset_with_cast,
|
||||
clippy::useless_transmute,
|
||||
clippy::missing_safety_doc,
|
||||
clippy::too_many_arguments
|
||||
)]
|
||||
|
||||
use common::Zeroable;
|
||||
use glib_sys::{GHashTable, GHashTableIter, GPtrArray, GSList};
|
||||
|
||||
#[cfg(MESON)]
|
||||
include!("bindings.inc.rs");
|
||||
|
||||
#[cfg(not(MESON))]
|
||||
include!(concat!(env!("OUT_DIR"), "/bindings.inc.rs"));
|
||||
|
||||
unsafe impl Send for VMStateDescription {}
|
||||
unsafe impl Sync for VMStateDescription {}
|
||||
|
||||
unsafe impl Send for VMStateField {}
|
||||
unsafe impl Sync for VMStateField {}
|
||||
|
||||
unsafe impl Send for VMStateInfo {}
|
||||
unsafe impl Sync for VMStateInfo {}
|
||||
|
||||
// bindgen does not derive Default here
|
||||
#[allow(clippy::derivable_impls)]
|
||||
impl Default for VMStateFlags {
|
||||
fn default() -> Self {
|
||||
Self(0)
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Zeroable for VMStateFlags {}
|
||||
unsafe impl Zeroable for VMStateField {}
|
||||
unsafe impl Zeroable for VMStateDescription {}
|
||||
@@ -1,7 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
pub mod bindings;
|
||||
|
||||
pub use migration_sys as bindings;
|
||||
pub use qemu_macros::ToMigrationState;
|
||||
|
||||
pub mod migratable;
|
||||
|
||||
@@ -165,79 +165,6 @@ macro_rules! vmstate_of {
|
||||
};
|
||||
}
|
||||
|
||||
pub trait VMStateFlagsExt {
|
||||
const VMS_VARRAY_FLAGS: VMStateFlags;
|
||||
}
|
||||
|
||||
impl VMStateFlagsExt for VMStateFlags {
|
||||
const VMS_VARRAY_FLAGS: VMStateFlags = VMStateFlags(
|
||||
VMStateFlags::VMS_VARRAY_INT32.0
|
||||
| VMStateFlags::VMS_VARRAY_UINT8.0
|
||||
| VMStateFlags::VMS_VARRAY_UINT16.0
|
||||
| VMStateFlags::VMS_VARRAY_UINT32.0,
|
||||
);
|
||||
}
|
||||
|
||||
// Add a couple builder-style methods to VMStateField, allowing
|
||||
// easy derivation of VMStateField constants from other types.
|
||||
impl VMStateField {
|
||||
#[must_use]
|
||||
pub const fn with_version_id(mut self, version_id: i32) -> Self {
|
||||
assert!(version_id >= 0);
|
||||
self.version_id = version_id;
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn with_array_flag(mut self, num: usize) -> Self {
|
||||
assert!(num <= 0x7FFF_FFFFusize);
|
||||
assert!((self.flags.0 & VMStateFlags::VMS_ARRAY.0) == 0);
|
||||
assert!((self.flags.0 & VMStateFlags::VMS_VARRAY_FLAGS.0) == 0);
|
||||
if (self.flags.0 & VMStateFlags::VMS_POINTER.0) != 0 {
|
||||
self.flags = VMStateFlags(self.flags.0 & !VMStateFlags::VMS_POINTER.0);
|
||||
self.flags = VMStateFlags(self.flags.0 | VMStateFlags::VMS_ARRAY_OF_POINTER.0);
|
||||
// VMS_ARRAY_OF_POINTER flag stores the size of pointer.
|
||||
// FIXME: *const, *mut, NonNull and Box<> have the same size as usize.
|
||||
// Resize if more smart pointers are supported.
|
||||
self.size = std::mem::size_of::<usize>();
|
||||
}
|
||||
self.flags = VMStateFlags(self.flags.0 & !VMStateFlags::VMS_SINGLE.0);
|
||||
self.flags = VMStateFlags(self.flags.0 | VMStateFlags::VMS_ARRAY.0);
|
||||
self.num = num as i32;
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn with_pointer_flag(mut self) -> Self {
|
||||
assert!((self.flags.0 & VMStateFlags::VMS_POINTER.0) == 0);
|
||||
self.flags = VMStateFlags(self.flags.0 | VMStateFlags::VMS_POINTER.0);
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn with_varray_flag_unchecked(mut self, flag: VMStateFlags) -> Self {
|
||||
self.flags = VMStateFlags(self.flags.0 & !VMStateFlags::VMS_ARRAY.0);
|
||||
self.flags = VMStateFlags(self.flags.0 | flag.0);
|
||||
self.num = 0; // varray uses num_offset instead of num.
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
#[allow(unused_mut)]
|
||||
pub const fn with_varray_flag(mut self, flag: VMStateFlags) -> Self {
|
||||
assert!((self.flags.0 & VMStateFlags::VMS_ARRAY.0) != 0);
|
||||
self.with_varray_flag_unchecked(flag)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn with_varray_multiply(mut self, num: u32) -> Self {
|
||||
assert!(num <= 0x7FFF_FFFFu32);
|
||||
self.flags = VMStateFlags(self.flags.0 | VMStateFlags::VMS_MULTIPLY_ELEMENTS.0);
|
||||
self.num = num as i32;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// This macro can be used (by just passing it a type) to forward the `VMState`
|
||||
/// trait to the first field of a tuple. This is a workaround for lack of
|
||||
/// support of nested [`offset_of`](core::mem::offset_of) until Rust 1.82.0.
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* QEMU System Emulator
|
||||
*
|
||||
* Copyright (c) 2024 Linaro Ltd.
|
||||
*
|
||||
* Authors: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This header file is meant to be used as input to the `bindgen` application
|
||||
* in order to generate C FFI compatible Rust bindings.
|
||||
*/
|
||||
|
||||
#ifndef __CLANG_STDATOMIC_H
|
||||
#define __CLANG_STDATOMIC_H
|
||||
/*
|
||||
* Fix potential missing stdatomic.h error in case bindgen does not insert the
|
||||
* correct libclang header paths on its own. We do not use stdatomic.h symbols
|
||||
* in QEMU code, so it's fine to declare dummy types instead.
|
||||
*/
|
||||
typedef enum memory_order {
|
||||
memory_order_relaxed,
|
||||
memory_order_consume,
|
||||
memory_order_acquire,
|
||||
memory_order_release,
|
||||
memory_order_acq_rel,
|
||||
memory_order_seq_cst,
|
||||
} memory_order;
|
||||
#endif /* __CLANG_STDATOMIC_H */
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "migration/vmstate.h"
|
||||
@@ -18,6 +18,7 @@ bql = { path = "../bql" }
|
||||
migration = { path = "../migration" }
|
||||
qemu_macros = { path = "../qemu-macros" }
|
||||
util = { path = "../util" }
|
||||
qom-sys = { path = "../bindings/qom-sys" }
|
||||
glib-sys.workspace = true
|
||||
|
||||
[lints]
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
../util/build.rs
|
||||
@@ -1,33 +1,8 @@
|
||||
# TODO: Remove this comment when the clang/libclang mismatch issue is solved.
|
||||
#
|
||||
# Rust bindings generation with `bindgen` might fail in some cases where the
|
||||
# detected `libclang` does not match the expected `clang` version/target. In
|
||||
# this case you must pass the path to `clang` and `libclang` to your build
|
||||
# command invocation using the environment variables CLANG_PATH and
|
||||
# LIBCLANG_PATH
|
||||
_qom_bindings_inc_rs = rust.bindgen(
|
||||
input: 'wrapper.h',
|
||||
dependencies: common_ss.all_dependencies(),
|
||||
output: 'bindings.inc.rs',
|
||||
include_directories: bindings_incdir,
|
||||
bindgen_version: ['>=0.60.0'],
|
||||
args: bindgen_args_common,
|
||||
c_args: bindgen_c_args,
|
||||
)
|
||||
|
||||
_qom_rs = static_library(
|
||||
'qom',
|
||||
structured_sources(
|
||||
[
|
||||
'src/lib.rs',
|
||||
'src/bindings.rs',
|
||||
'src/prelude.rs',
|
||||
'src/qom.rs',
|
||||
],
|
||||
{'.': _qom_bindings_inc_rs}
|
||||
),
|
||||
'src/lib.rs',
|
||||
link_with: [_bql_rs, _migration_rs],
|
||||
dependencies: [common_rs, glib_sys_rs, qemu_macros],
|
||||
dependencies: [common_rs, glib_sys_rs, qemu_macros, qom_sys_rs],
|
||||
)
|
||||
|
||||
qom_rs = declare_dependency(link_with: [_qom_rs], dependencies: [qemu_macros, qom, qemuutil])
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
pub use qemu_macros::Object;
|
||||
|
||||
pub mod bindings;
|
||||
pub use qom_sys as bindings;
|
||||
|
||||
// preserve one-item-per-"use" syntax, it is clearer
|
||||
// for prelude-like modules
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/*
|
||||
* This header file is meant to be used as input to the `bindgen` application
|
||||
* in order to generate C FFI compatible Rust bindings.
|
||||
*/
|
||||
|
||||
#ifndef __CLANG_STDATOMIC_H
|
||||
#define __CLANG_STDATOMIC_H
|
||||
/*
|
||||
* Fix potential missing stdatomic.h error in case bindgen does not insert the
|
||||
* correct libclang header paths on its own. We do not use stdatomic.h symbols
|
||||
* in QEMU code, so it's fine to declare dummy types instead.
|
||||
*/
|
||||
typedef enum memory_order {
|
||||
memory_order_relaxed,
|
||||
memory_order_consume,
|
||||
memory_order_acquire,
|
||||
memory_order_release,
|
||||
memory_order_acq_rel,
|
||||
memory_order_seq_cst,
|
||||
} memory_order;
|
||||
#endif /* __CLANG_STDATOMIC_H */
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
|
||||
#include "qom/object.h"
|
||||
@@ -14,6 +14,9 @@ rust-version.workspace = true
|
||||
|
||||
[dependencies]
|
||||
common = { path = "../common" }
|
||||
system-sys = { path = "../bindings/system-sys" }
|
||||
bql = { path = "../bql" }
|
||||
migration = { path = "../migration" }
|
||||
qom = { path = "../qom" }
|
||||
util = { path = "../util" }
|
||||
glib-sys.workspace = true
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
../util/build.rs
|
||||
@@ -1,41 +1,8 @@
|
||||
c_enums = [
|
||||
'device_endian',
|
||||
]
|
||||
_system_bindgen_args = []
|
||||
foreach enum : c_enums
|
||||
_system_bindgen_args += ['--rustified-enum', enum]
|
||||
endforeach
|
||||
|
||||
# TODO: Remove this comment when the clang/libclang mismatch issue is solved.
|
||||
#
|
||||
# Rust bindings generation with `bindgen` might fail in some cases where the
|
||||
# detected `libclang` does not match the expected `clang` version/target. In
|
||||
# this case you must pass the path to `clang` and `libclang` to your build
|
||||
# command invocation using the environment variables CLANG_PATH and
|
||||
# LIBCLANG_PATH
|
||||
_system_bindings_inc_rs = rust.bindgen(
|
||||
input: 'wrapper.h',
|
||||
dependencies: common_ss.all_dependencies(),
|
||||
output: 'bindings.inc.rs',
|
||||
include_directories: bindings_incdir,
|
||||
bindgen_version: ['>=0.60.0'],
|
||||
args: bindgen_args_common + _system_bindgen_args,
|
||||
c_args: bindgen_c_args,
|
||||
)
|
||||
|
||||
_system_rs = static_library(
|
||||
'system',
|
||||
structured_sources(
|
||||
[
|
||||
'src/lib.rs',
|
||||
'src/bindings.rs',
|
||||
'src/memory.rs',
|
||||
'src/prelude.rs',
|
||||
],
|
||||
{'.': _system_bindings_inc_rs}
|
||||
),
|
||||
'src/lib.rs',
|
||||
link_with: [_bql_rs, _migration_rs, _qom_rs, _util_rs],
|
||||
dependencies: [glib_sys_rs, common_rs, qemu_macros],
|
||||
dependencies: [glib_sys_rs, common_rs, qemu_macros, system_sys_rs],
|
||||
)
|
||||
|
||||
system_rs = declare_dependency(link_with: [_system_rs],
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
pub mod bindings;
|
||||
pub use system_sys as bindings;
|
||||
|
||||
mod memory;
|
||||
pub use memory::*;
|
||||
|
||||
@@ -132,7 +132,7 @@ unsafe impl Sync for MemoryRegion {}
|
||||
impl MemoryRegion {
|
||||
unsafe fn do_init_io(
|
||||
slot: *mut bindings::MemoryRegion,
|
||||
owner: *mut bindings::Object,
|
||||
owner: *mut qom::bindings::Object,
|
||||
ops: &'static bindings::MemoryRegionOps,
|
||||
name: &'static str,
|
||||
size: u64,
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/*
|
||||
* This header file is meant to be used as input to the `bindgen` application
|
||||
* in order to generate C FFI compatible Rust bindings.
|
||||
*/
|
||||
|
||||
#ifndef __CLANG_STDATOMIC_H
|
||||
#define __CLANG_STDATOMIC_H
|
||||
/*
|
||||
* Fix potential missing stdatomic.h error in case bindgen does not insert the
|
||||
* correct libclang header paths on its own. We do not use stdatomic.h symbols
|
||||
* in QEMU code, so it's fine to declare dummy types instead.
|
||||
*/
|
||||
typedef enum memory_order {
|
||||
memory_order_relaxed,
|
||||
memory_order_consume,
|
||||
memory_order_acquire,
|
||||
memory_order_release,
|
||||
memory_order_acq_rel,
|
||||
memory_order_seq_cst,
|
||||
} memory_order;
|
||||
#endif /* __CLANG_STDATOMIC_H */
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
|
||||
#include "system/system.h"
|
||||
#include "system/memory.h"
|
||||
#include "system/address-spaces.h"
|
||||
@@ -18,6 +18,7 @@ foreign = { workspace = true }
|
||||
glib-sys = { workspace = true }
|
||||
libc = { workspace = true }
|
||||
common = { path = "../common" }
|
||||
util-sys = { path = "../bindings/util-sys" }
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
@@ -1,45 +1,7 @@
|
||||
_util_bindgen_args = []
|
||||
c_enums = [
|
||||
'module_init_type',
|
||||
'QEMUClockType',
|
||||
]
|
||||
foreach enum : c_enums
|
||||
_util_bindgen_args += ['--rustified-enum', enum]
|
||||
endforeach
|
||||
|
||||
#
|
||||
# TODO: Remove this comment when the clang/libclang mismatch issue is solved.
|
||||
#
|
||||
# Rust bindings generation with `bindgen` might fail in some cases where the
|
||||
# detected `libclang` does not match the expected `clang` version/target. In
|
||||
# this case you must pass the path to `clang` and `libclang` to your build
|
||||
# command invocation using the environment variables CLANG_PATH and
|
||||
# LIBCLANG_PATH
|
||||
_util_bindings_inc_rs = rust.bindgen(
|
||||
input: 'wrapper.h',
|
||||
dependencies: common_ss.all_dependencies(),
|
||||
output: 'bindings.inc.rs',
|
||||
include_directories: bindings_incdir,
|
||||
bindgen_version: ['>=0.60.0'],
|
||||
args: bindgen_args_common + _util_bindgen_args,
|
||||
c_args: bindgen_c_args,
|
||||
)
|
||||
|
||||
_util_rs = static_library(
|
||||
'util',
|
||||
structured_sources(
|
||||
[
|
||||
'src/lib.rs',
|
||||
'src/bindings.rs',
|
||||
'src/error.rs',
|
||||
'src/log.rs',
|
||||
'src/module.rs',
|
||||
'src/prelude.rs',
|
||||
'src/timer.rs',
|
||||
],
|
||||
{'.': _util_bindings_inc_rs}
|
||||
),
|
||||
dependencies: [anyhow_rs, libc_rs, foreign_rs, glib_sys_rs, common_rs],
|
||||
'src/lib.rs',
|
||||
dependencies: [anyhow_rs, libc_rs, foreign_rs, glib_sys_rs, common_rs, util_sys_rs],
|
||||
)
|
||||
|
||||
util_rs = declare_dependency(link_with: [_util_rs], dependencies: [qemuutil, qom])
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
pub mod bindings;
|
||||
pub use util_sys as bindings;
|
||||
|
||||
pub mod error;
|
||||
pub mod log;
|
||||
pub mod module;
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/*
|
||||
* This header file is meant to be used as input to the `bindgen` application
|
||||
* in order to generate C FFI compatible Rust bindings.
|
||||
*/
|
||||
|
||||
#ifndef __CLANG_STDATOMIC_H
|
||||
#define __CLANG_STDATOMIC_H
|
||||
/*
|
||||
* Fix potential missing stdatomic.h error in case bindgen does not insert the
|
||||
* correct libclang header paths on its own. We do not use stdatomic.h symbols
|
||||
* in QEMU code, so it's fine to declare dummy types instead.
|
||||
*/
|
||||
typedef enum memory_order {
|
||||
memory_order_relaxed,
|
||||
memory_order_consume,
|
||||
memory_order_acquire,
|
||||
memory_order_release,
|
||||
memory_order_acq_rel,
|
||||
memory_order_seq_cst,
|
||||
} memory_order;
|
||||
#endif /* __CLANG_STDATOMIC_H */
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
|
||||
#include "qapi/error.h"
|
||||
#include "qapi/error-internal.h"
|
||||
#include "qemu/log-for-trace.h"
|
||||
#include "qemu/log.h"
|
||||
#include "qemu/module.h"
|
||||
#include "qemu/timer.h"
|
||||
Reference in New Issue
Block a user