diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8b8e800..f02c13d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,13 +10,23 @@ env: CARGO_TERM_COLOR: always jobs: - test_plugins_linux_v1: - name: Build and Test Plugins API v1 (Linux) + test_plugins_linux: + name: Build and Test Plugins API v${{ matrix.version }} (Linux) runs-on: ubuntu-latest container: ubuntu:24.04 + strategy: + matrix: + include: + - version: 1 + commit: fb691b8cbabf5bde7d25a7f720d5ec7d5b1341e1 + - version: 2 + commit: fba3b490a26cb278dfa183d7fcc375746e312980 + - version: 3 + commit: 7de77d37880d7267a491cb32a1b2232017d1e545 + - version: 4 + commit: cfa3a6c54511374e9ccee26d9c38ac1698fc7af2 env: - # Hash of v1 - QEMU_COMMIT_HASH: fb691b8cbabf5bde7d25a7f720d5ec7d5b1341e1 + QEMU_COMMIT_HASH: ${{ matrix.commit }} steps: - name: Set up Sources List run: | @@ -45,98 +55,43 @@ jobs: Components: main universe restricted multiverse Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg EOF - - name: Install QEMU Build Dependencies - run: | - apt -y update && \ - apt -y install git curl build-essential && \ - apt -y source qemu && \ - apt -y build-dep qemu - - # Clone without history - - name: Clone QEMU - run: | - git clone https://github.com/qemu/qemu qemu-upstream - cd qemu-upstream - git checkout "${QEMU_COMMIT_HASH}" - - - name: Build QEMU - run: | - cd qemu-upstream - ./configure --enable-plugins - cd build - make -j$(nproc) - make install - cd ../.. - - - uses: dtolnay/rust-toolchain@nightly - - uses: actions/checkout@v4 - - name: Test QEMU Install - run: | - qemu-x86_64 --help - - name: Build and Test Tracer - run: | - cd plugins/tracer - cargo build -r --features=plugin-api-v1 --no-default-features || exit 0 - cargo build -r --features=plugin-api-v1 --no-default-features - cargo run --features=plugin-api-v1 --no-default-features -r --bin tracer -- -a /bin/ls -- -lah - cd ../.. - - name: Build and Test Tiny - run: | - cd plugins/tiny - cargo build -r --features=plugin-api-v1 --no-default-features - qemu-x86_64 -plugin ../../target/release/libtiny.so /bin/ls -lah - cd ../.. - - test_plugins_linux_v2: - name: Build and Test Plugins API v2 (Linux) - runs-on: ubuntu-latest - container: ubuntu:24.04 - env: - # Hash of v2 - QEMU_COMMIT_HASH: fba3b490a26cb278dfa183d7fcc375746e312980 - steps: - - name: Set up Sources List - run: | - cat < /etc/apt/sources.list.d/ubuntu.sources - Types: deb - URIs: http://archive.ubuntu.com/ubuntu/ - Suites: noble noble-updates noble-backports - Components: main universe restricted multiverse - Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg - Types: deb - URIs: http://security.ubuntu.com/ubuntu/ - Suites: noble-security - Components: main universe restricted multiverse - Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg - - Types: deb-src - URIs: http://archive.ubuntu.com/ubuntu/ - Suites: noble noble-updates noble-backports - Components: main universe restricted multiverse - Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg + # Cache apt packages + - name: Cache APT packages + id: apt-cache + uses: actions/cache@v3 + with: + path: /var/cache/apt/archives + key: ${{ runner.os }}-apt-${{ hashFiles('/etc/apt/sources.list.d/ubuntu.sources') }} - Types: deb - URIs: http://security.ubuntu.com/ubuntu/ - Suites: noble-security - Components: main universe restricted multiverse - Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg - EOF - name: Install QEMU Build Dependencies run: | - apt -y update && \ - apt -y install git curl build-essential && \ - apt -y source qemu && \ + apt -y update + apt -y install git curl build-essential + apt -y source qemu apt -y build-dep qemu - # Clone without history + # Cache QEMU source and build + - name: Cache QEMU + id: qemu-cache + uses: actions/cache@v3 + with: + path: | + qemu-upstream + qemu-upstream/build + key: ${{ runner.os }}-qemu-v${{ matrix.version }}-${{ matrix.commit }} + + # Clone only if cache miss - name: Clone QEMU + if: steps.qemu-cache.outputs.cache-hit != 'true' run: | - git clone https://github.com/qemu/qemu qemu-upstream + git clone https://gitlab.com/qemu/qemu qemu-upstream cd qemu-upstream git checkout "${QEMU_COMMIT_HASH}" + # Build only if cache miss - name: Build QEMU + if: steps.qemu-cache.outputs.cache-hit != 'true' run: | cd qemu-upstream ./configure --enable-plugins @@ -147,97 +102,35 @@ jobs: - uses: dtolnay/rust-toolchain@nightly - uses: actions/checkout@v4 - - name: Test QEMU Install - run: | - qemu-x86_64 --help - - name: Build and Test Tracer - run: | - cd plugins/tracer - cargo build -r --features=plugin-api-v2 --no-default-features || exit 0 - cargo build -r --features=plugin-api-v2 --no-default-features - cargo run --features=plugin-api-v2 --no-default-features -r --bin tracer -- -a /bin/ls -- -lah - cd ../.. - - name: Build and Test Tiny - run: | - cd plugins/tiny - cargo build -r --features=plugin-api-v2 --no-default-features - qemu-x86_64 -plugin ../../target/release/libtiny.so /bin/ls -lah - cd ../.. - test_plugins_linux_v3: - name: Build and Test Plugins API V3 (Linux) - runs-on: ubuntu-latest - container: ubuntu:24.04 - env: - # Hash of v3 - QEMU_COMMIT_HASH: 7de77d37880d7267a491cb32a1b2232017d1e545 - steps: - - name: Set up Sources List - run: | - cat < /etc/apt/sources.list.d/ubuntu.sources - Types: deb - URIs: http://archive.ubuntu.com/ubuntu/ - Suites: noble noble-updates noble-backports - Components: main universe restricted multiverse - Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg - - Types: deb - URIs: http://security.ubuntu.com/ubuntu/ - Suites: noble-security - Components: main universe restricted multiverse - Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg - - Types: deb-src - URIs: http://archive.ubuntu.com/ubuntu/ - Suites: noble noble-updates noble-backports - Components: main universe restricted multiverse - Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg - - Types: deb - URIs: http://security.ubuntu.com/ubuntu/ - Suites: noble-security - Components: main universe restricted multiverse - Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg - EOF - - name: Install QEMU Build Dependencies - run: | - apt -y update && \ - apt -y install git curl build-essential && \ - apt -y source qemu && \ - apt -y build-dep qemu - - # Clone without history - - name: Clone QEMU - run: | - git clone https://github.com/qemu/qemu qemu-upstream - cd qemu-upstream - git checkout "${QEMU_COMMIT_HASH}" - - - name: Build QEMU - run: | - cd qemu-upstream - ./configure --enable-plugins - cd build - make -j$(nproc) - make install - cd ../.. + # Cache Rust dependencies + - name: Cache Rust dependencies + uses: actions/cache@v3 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + target + key: ${{ runner.os }}-rust-v${{ matrix.version }}-${{ hashFiles('**/Cargo.lock') }} + restore-keys: | + ${{ runner.os }}-rust-v${{ matrix.version }}- - - uses: dtolnay/rust-toolchain@nightly - - uses: actions/checkout@v4 - name: Test QEMU Install run: | qemu-x86_64 --help + - name: Build and Test Tracer run: | cd plugins/tracer - cargo build -r --features=plugin-api-v3 --no-default-features || exit 0 - cargo build -r --features=plugin-api-v3 --no-default-features - cargo run --features=plugin-api-v3 --no-default-features -r --bin tracer -- -a /bin/ls -- -lah + cargo build -r --features=plugin-api-v${{ matrix.version }} --no-default-features || exit 0 + cargo build -r --features=plugin-api-v${{ matrix.version }} --no-default-features + cargo run --features=plugin-api-v${{ matrix.version }} --no-default-features -r --bin tracer -- -a /bin/ls -- -lah cd ../.. + - name: Build and Test Tiny run: | cd plugins/tiny - cargo build -r --features=plugin-api-v3 --no-default-features + cargo build -r --features=plugin-api-v${{ matrix.version }} --no-default-features qemu-x86_64 -plugin ../../target/release/libtiny.so /bin/ls -lah cd ../.. @@ -245,12 +138,9 @@ jobs: name: Build and Test Plugins (Windows) runs-on: windows-latest env: - # QEMU 9.0.0 - # NOTE: This installer does not work headless - # QEMU_URL: "https://qemu.weilnetz.de/w64/2023/qemu-w64-setup-20231224.exe" + QEMU_VERSION: 9.1.2-1 RUSTUP_URL: "https://win.rustup.rs/x86_64" FEDORA_CLOUDIMG_URL: "https://download.fedoraproject.org/pub/fedora/linux/releases/39/Cloud/x86_64/images/Fedora-Cloud-Base-39-1.5.x86_64.qcow2" - steps: - uses: msys2/setup-msys2@v2 with: @@ -259,6 +149,13 @@ jobs: install: git mingw-w64-ucrt-x86_64-gcc location: C:\msys-custom + # Cache MSYS2 packages + - name: Cache MSYS2 packages + uses: actions/cache@v3 + with: + path: C:\msys-custom\msys64\var\cache\pacman\pkg + key: ${{ runner.os }}-msys2-${{ env.QEMU_VERSION }} + - name: Download and Install Rust run: | $ProgressPreference = 'SilentlyContinue' @@ -269,7 +166,7 @@ jobs: shell: msys2 {0} run: | pacman -Syu --noconfirm - pacman -Sy mingw-w64-ucrt-x86_64-qemu --noconfirm + pacman -Sy mingw-w64-ucrt-x86_64-qemu=${QEMU_VERSION} --noconfirm - name: Test QEMU run: | @@ -277,12 +174,33 @@ jobs: - uses: actions/checkout@v4 + # Cache downloaded Fedora image + - name: Cache Fedora Cloud Image + id: fedora-cache + uses: actions/cache@v3 + with: + path: Fedora-Cloud-Base-39-1.5.x86_64.qcow2 + key: fedora-cloud-39-1.5 + - name: Download Cloud Image + if: steps.fedora-cache.outputs.cache-hit != 'true' run: | $ProgressPreference = 'SilentlyContinue' Invoke-WebRequest -Uri ${{ env.FEDORA_CLOUDIMG_URL }} -OutFile Fedora-Cloud-Base-39-1.5.x86_64.qcow2 ls + # Cache Rust dependencies for Windows + - name: Cache Rust dependencies + uses: actions/cache@v3 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + target + key: ${{ runner.os }}-rust-${{ hashFiles('**/Cargo.lock') }} + restore-keys: | + ${{ runner.os }}-rust- + - name: Build and Test Tiny run: | cd plugins/tiny-system @@ -294,4 +212,4 @@ jobs: echo "Stopping process" Stop-Process -Id $process.id -ErrorAction SilentlyContinue cat out.txt - cat err.txt + cat err.txt \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index f9b2e2f..dd77087 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,16 +4,15 @@ categories = ["virtualization", "emulator", "qemu"] description = "Rust bindings and binary installers for QEMU" edition = "2021" homepage = "https://github.com/novafacing/qemu-rs" -license = "GPL-2.0-only" +license = "GPL-2.0-or-later" publish = true readme = "README.md" repository = "https://github.com/novafacing/qemu-rs" -version = "9.0.0-v0" +version = "9.2.0-v0" [workspace] resolver = "2" members = [ - "qemu", "qemu-plugin", "qemu-plugin-sys", "plugins/tiny", @@ -23,6 +22,5 @@ members = [ default-members = ["qemu-plugin", "qemu-plugin-sys"] [workspace.dependencies] -qemu-plugin-sys = { version = "9.0.0-v0", path = "qemu-plugin-sys", default-features = false } -qemu-plugin = { version = "9.0.0-v0", path = "qemu-plugin", default-features = false } -qemu = { version = "9.0.0-v0", path = "qemu" } +qemu-plugin-sys = { version = "9.2.0-v0", path = "qemu-plugin-sys", default-features = false } +qemu-plugin = { version = "9.2.0-v0", path = "qemu-plugin", default-features = false } diff --git a/README.md b/README.md index ffdef46..a86c1ce 100644 --- a/README.md +++ b/README.md @@ -21,20 +21,4 @@ and instructions) of a program like: ```sh cargo run -r --bin tracer -- -a /bin/ls -- -lah -``` - -## Installing QEMU - -This repository also provides a crate (`qemu`) which builds QEMU from source and -installs Rust wrappers for QEMU as binaries. - -You can install QEMU with (add any additional features you need, e.g. `plugins`): - -```sh -cargo install qemu@9.0.0-v0 --features=binaries -``` - -On some systems, particularly BTRFS systems, `/tmp` may not be large enough for the -temporary build directory (QEMU is quite large to build). In this case, create a -directory on your root filesystem (e.g. `$HOME/.cargo/tmp`) and set -`CARGO_TARGET_DIR=$HOME/.cargo/tmp` when running the install command. \ No newline at end of file +``` \ No newline at end of file diff --git a/plugins/tiny-system/Cargo.toml b/plugins/tiny-system/Cargo.toml index 6cd466c..b2c4d49 100644 --- a/plugins/tiny-system/Cargo.toml +++ b/plugins/tiny-system/Cargo.toml @@ -10,12 +10,13 @@ crate-type = ["cdylib"] qemu-plugin = { workspace = true, features = [ "unix-weak-link", ], default-features = false } -anyhow = "1.0.75" -ffi = "0.1.0" -ctor = "0.2.6" +anyhow = "1.0.94" +ffi = "0.1.1" +ctor = "0.2.9" [features] -default = ["plugin-api-v2"] +default = ["plugin-api-v4"] plugin-api-v1 = ["qemu-plugin/plugin-api-v1"] plugin-api-v2 = ["qemu-plugin/plugin-api-v2"] plugin-api-v3 = ["qemu-plugin/plugin-api-v3"] +plugin-api-v4 = ["qemu-plugin/plugin-api-v4"] diff --git a/plugins/tiny/Cargo.toml b/plugins/tiny/Cargo.toml index d9d92e8..3c64316 100644 --- a/plugins/tiny/Cargo.toml +++ b/plugins/tiny/Cargo.toml @@ -10,12 +10,13 @@ crate-type = ["cdylib"] qemu-plugin = { workspace = true, features = [ "unix-weak-link", ], default-features = false } -anyhow = "1.0.75" -ffi = "0.1.0" -ctor = "0.2.6" +anyhow = "1.0.94" +ffi = "0.1.1" +ctor = "0.2.9" [features] -default = ["plugin-api-v2"] +default = ["plugin-api-v4"] plugin-api-v1 = ["qemu-plugin/plugin-api-v1"] plugin-api-v2 = ["qemu-plugin/plugin-api-v2"] plugin-api-v3 = ["qemu-plugin/plugin-api-v3"] +plugin-api-v4 = ["qemu-plugin/plugin-api-v4"] diff --git a/plugins/tiny/src/lib.rs b/plugins/tiny/src/lib.rs index 5d01dce..7168fcf 100644 --- a/plugins/tiny/src/lib.rs +++ b/plugins/tiny/src/lib.rs @@ -4,13 +4,13 @@ use qemu_plugin::{ plugin::{HasCallbacks, Plugin, Register, PLUGIN}, PluginId, TranslationBlock, }; -#[cfg(any(feature = "plugin-api-v2", feature = "plugin-api-v3"))] +#[cfg(not(feature = "plugin-api-v1"))] use qemu_plugin::{qemu_plugin_get_registers, RegisterDescriptor, VCPUIndex}; use std::sync::Mutex; #[derive(Default)] struct TinyTrace { - #[cfg(any(feature = "plugin-api-v2", feature = "plugin-api-v3"))] + #[cfg(not(feature = "plugin-api-v1"))] registers: Vec>, } @@ -18,7 +18,7 @@ impl Plugin for TinyTrace {} impl Register for TinyTrace {} impl HasCallbacks for TinyTrace { - #[cfg(any(feature = "plugin-api-v2", feature = "plugin-api-v3"))] + #[cfg(not(feature = "plugin-api-v1"))] fn on_vcpu_init(&mut self, _id: PluginId, _vcpu_id: VCPUIndex) -> Result<()> { self.registers = qemu_plugin_get_registers()?; Ok(()) diff --git a/plugins/tracer/Cargo.toml b/plugins/tracer/Cargo.toml index 1889dc0..0a95582 100644 --- a/plugins/tracer/Cargo.toml +++ b/plugins/tracer/Cargo.toml @@ -8,30 +8,27 @@ name = "tracer" crate-type = ["cdylib", "lib"] [dependencies] -anyhow = "1.0.75" -ctor = "0.2.6" +anyhow = "1.0.94" +ctor = "0.2.9" qemu-plugin = { workspace = true, features = [ "unix-weak-link", ], default-features = false } -serde = { version = "1.0.193", features = ["derive"] } +serde = { version = "1.0.215", features = ["derive"] } serde_cbor = "0.11.2" -tokio = { version = "1.35.0", features = ["full"] } -typed-builder = "0.18.0" -yaxpeax-x86 = "1.2.2" +tokio = { version = "1.42.0", features = ["full"] } +typed-builder = "0.20.0" +yaxpeax-x86 = "2.0.0" # Dependencies only used by this crate's `tracer` binary. We do not use dev-dependencies # because they cannot be optional. -clap = { version = "4.4.11", features = ["derive", "string"] } -# Enable the `qemu` feature to build and install QEMU with the `qemu` crate instead -# of trying to use the system QEMU. -qemu = { workspace = true, features = ["plugins"], optional = true } +clap = { version = "4.5.22", features = ["derive", "string"] } memfd-exec = { version = "0.2.1", optional = true } rand = "0.8.5" -serde_json = "1.0.108" +serde_json = "1.0.133" [features] -qemu = ["dep:memfd-exec", "dep:qemu"] -default = ["plugin-api-v2"] +default = ["plugin-api-v4"] plugin-api-v1 = ["qemu-plugin/plugin-api-v1"] plugin-api-v2 = ["qemu-plugin/plugin-api-v2"] plugin-api-v3 = ["qemu-plugin/plugin-api-v3"] +plugin-api-v4 = ["qemu-plugin/plugin-api-v4"] diff --git a/plugins/tracer/src/bin/tracer.rs b/plugins/tracer/src/bin/tracer.rs index 30b47c6..47b7f6d 100644 --- a/plugins/tracer/src/bin/tracer.rs +++ b/plugins/tracer/src/bin/tracer.rs @@ -1,13 +1,8 @@ use anyhow::{anyhow, Error, Result}; use clap::Parser; -#[cfg(feature = "qemu")] -use memfd_exec::{MemFdExecutable, Stdio}; -#[cfg(feature = "qemu")] -use qemu::QEMU_X86_64_LINUX_USER; use rand::{distributions::Alphanumeric, thread_rng, Rng}; use serde_cbor::Deserializer; use serde_json::to_string; -#[cfg(not(feature = "qemu"))] use std::process::{Command, Stdio}; use std::{ fs::OpenOptions, @@ -78,7 +73,7 @@ struct Args { pub args: Vec, } -#[cfg(any(feature = "plugin-api-v2", feature = "plugin-api-v3"))] +#[cfg(not(feature = "plugin-api-v1"))] #[derive(Parser, Debug, Clone)] /// Run QEMU with a plugin that logs events. To pass arguments to QEMU, use the QEMU environment /// variables. @@ -123,7 +118,7 @@ impl Args { self.log_syscalls | self.log_all, ) } - #[cfg(any(feature = "plugin-api-v2", feature = "plugin-api-v3"))] + #[cfg(not(feature = "plugin-api-v1"))] { format!( "log_insns={},log_mem={},log_syscalls={},log_registers={}", @@ -157,82 +152,6 @@ impl Args { } } -#[cfg(feature = "qemu")] -async fn run(input: Option>, args: Vec) -> Result<()> { - let mut exe = MemFdExecutable::new("qemu", QEMU_X86_64_LINUX_USER) - .args(args) - .stdin(if input.is_some() { - Stdio::piped() - } else { - Stdio::inherit() - }) - .stdout(Stdio::piped()) - .stderr(Stdio::piped()) - .spawn()?; - - if let Some(input) = input { - let mut stdin = exe.stdin.take().ok_or_else(|| anyhow!("No stdin"))?; - spawn_blocking(move || stdin.write_all(&input)); - } - - let stdout = exe.stdout.take().ok_or_else(|| anyhow!("No stdout"))?; - - let out_reader = spawn_blocking(move || { - let mut line = String::new(); - let mut out_reader = BufReader::new(stdout); - - loop { - line.clear(); - - if let 0 = out_reader.read_line(&mut line)? { - break; - } - - let line = line.trim(); - - if !line.is_empty() { - println!("{line}"); - } - } - - Ok::<(), Error>(()) - }); - - let stderr = exe.stderr.take().ok_or_else(|| anyhow!("No stderr"))?; - - let err_reader = spawn_blocking(move || { - let mut line = String::new(); - let mut err_reader = BufReader::new(stderr); - - loop { - line.clear(); - - if let 0 = err_reader.read_line(&mut line)? { - break; - } - - let line = line.trim(); - - if !line.is_empty() { - eprintln!("{line}"); - } - } - - Ok::<(), Error>(()) - }); - - let waiter = spawn_blocking(move || exe.wait()); - - let (out_res, err_res, waiter_res) = join!(out_reader, err_reader, waiter); - - out_res??; - err_res??; - waiter_res??; - - Ok(()) -} - -#[cfg(not(feature = "qemu"))] async fn run(input: Option>, args: Vec) -> Result<()> { let mut exe = Command::new("qemu-x86_64") .args(args) diff --git a/plugins/tracer/src/lib.rs b/plugins/tracer/src/lib.rs index b0d8ada..d2d2cfe 100644 --- a/plugins/tracer/src/lib.rs +++ b/plugins/tracer/src/lib.rs @@ -1,11 +1,13 @@ use anyhow::{anyhow, Error, Result}; use ctor::ctor; +#[cfg(feature = "plugin-api-v4")] +use qemu_plugin::qemu_plugin_read_memory_vaddr; use qemu_plugin::{ install::{Args, Info, Value}, plugin::{HasCallbacks, Plugin, Register, PLUGIN}, Instruction, MemRW, MemoryInfo, PluginId, TranslationBlock, VCPUIndex, }; -#[cfg(any(feature = "plugin-api-v2", feature = "plugin-api-v3"))] +#[cfg(not(feature = "plugin-api-v1"))] use qemu_plugin::{qemu_plugin_get_registers, RegisterDescriptor}; use serde::{Deserialize, Serialize}; use serde_cbor::to_writer; @@ -95,9 +97,12 @@ pub struct SyscallEvent { pub num: i64, pub return_value: i64, pub args: [u64; 8], + #[cfg(feature = "plugin-api-v4")] + #[builder(default)] + pub buffers: HashMap>, } -#[cfg(any(feature = "plugin-api-v2", feature = "plugin-api-v3"))] +#[cfg(not(feature = "plugin-api-v1"))] #[derive(Clone, Debug, Deserialize, Serialize)] pub struct Registers(pub HashMap>); @@ -105,7 +110,7 @@ pub struct Registers(pub HashMap>); pub enum Event { Instruction { event: InstructionEvent, - #[cfg(any(feature = "plugin-api-v2", feature = "plugin-api-v3"))] + #[cfg(not(feature = "plugin-api-v1"))] registers: Registers, }, Memory(MemoryEvent), @@ -114,8 +119,10 @@ pub enum Event { #[derive(TypedBuilder, Clone, Debug)] struct Tracer { + #[builder(default)] + pub target_name: Option, pub syscalls: Arc>>, - #[cfg(any(feature = "plugin-api-v2", feature = "plugin-api-v3"))] + #[cfg(not(feature = "plugin-api-v1"))] pub registers: Arc>>>, #[builder(default)] pub tx: Arc>>, @@ -125,7 +132,7 @@ struct Tracer { pub log_mem: bool, #[builder(default)] pub log_syscalls: bool, - #[cfg(any(feature = "plugin-api-v2", feature = "plugin-api-v3"))] + #[cfg(not(feature = "plugin-api-v1"))] #[builder(default)] pub log_registers: bool, } @@ -138,7 +145,7 @@ impl Tracer { .syscalls(Arc::new(Mutex::new(HashMap::new()))) .build() } - #[cfg(any(feature = "plugin-api-v2", feature = "plugin-api-v3"))] + #[cfg(not(feature = "plugin-api-v1"))] { Self::builder() .syscalls(Arc::new(Mutex::new(HashMap::new()))) @@ -149,7 +156,7 @@ impl Tracer { } impl HasCallbacks for Tracer { - #[cfg(any(feature = "plugin-api-v2", feature = "plugin-api-v3"))] + #[cfg(not(feature = "plugin-api-v1"))] fn on_vcpu_init( &mut self, _id: PluginId, @@ -191,7 +198,7 @@ impl HasCallbacks for Tracer { }); } - #[cfg(any(feature = "plugin-api-v2", feature = "plugin-api-v3"))] + #[cfg(not(feature = "plugin-api-v1"))] if self.log_insns { let tx = self.tx.clone(); let registers = self @@ -269,12 +276,46 @@ impl HasCallbacks for Tracer { return Ok(()); } + #[cfg(any( + feature = "plugin-api-v1", + feature = "plugin-api-v2", + feature = "plugin-api-v3" + ))] let event = SyscallEvent::builder() .num(num) .return_value(-1) .args([a1, a2, a3, a4, a5, a6, a7, a8]) .build(); + #[cfg(feature = "plugin-api-v4")] + let event = { + let buffers = if let Some(write_sysno) = match self.target_name.as_deref() { + Some("i386") => Some(4), + Some("x86_64") => Some(1), + Some("arm") => Some(4), + Some("aarch64") => Some(64), + _ => None, + } { + if num == write_sysno { + let addr = a2; + let len = a3 as usize; + let buffer = qemu_plugin_read_memory_vaddr(addr, len)?; + [(1, buffer)].into_iter().collect::>() + } else { + Default::default() + } + } else { + Default::default() + }; + + SyscallEvent::builder() + .num(num) + .return_value(-1) + .args([a1, a2, a3, a4, a5, a6, a7, a8]) + .buffers(buffers) + .build() + }; + let mut syscalls = self .syscalls .lock() @@ -295,7 +336,7 @@ impl HasCallbacks for Tracer { &mut self, id: PluginId, vcpu_index: VCPUIndex, - _: i64, + num: i64, ret: i64, ) -> Result<()> { if !self.log_syscalls { @@ -317,6 +358,24 @@ impl HasCallbacks for Tracer { ) .ok_or_else(|| anyhow!("No syscall event found"))?; + #[cfg(feature = "plugin-api-v4")] + { + if let Some(read_sysno) = match self.target_name.as_deref() { + Some("i386") => Some(3), + Some("x86_64") => Some(0), + Some("arm") => Some(3), + Some("aarch64") => Some(63), + _ => None, + } { + if num == read_sysno { + let addr = event.args[1]; + let len = event.args[2] as usize; + let buffer = qemu_plugin_read_memory_vaddr(addr, len)?; + event.buffers.insert(1, buffer); + } + } + } + // Update the return value event.return_value = ret; @@ -338,7 +397,7 @@ pub struct PluginArgs { pub log_insns: bool, pub log_mem: bool, pub log_syscalls: bool, - #[cfg(any(feature = "plugin-api-v2", feature = "plugin-api-v3"))] + #[cfg(not(feature = "plugin-api-v1"))] pub log_registers: bool, pub socket_path: PathBuf, } @@ -386,7 +445,7 @@ impl TryFrom<&Args> for PluginArgs { ) .build()) } - #[cfg(any(feature = "plugin-api-v2", feature = "plugin-api-v3"))] + #[cfg(not(feature = "plugin-api-v1"))] { Ok(Self::builder() .log_insns( @@ -436,9 +495,11 @@ impl TryFrom<&Args> for PluginArgs { } impl Register for Tracer { - fn register(&mut self, _: PluginId, args: &Args, _: &Info) -> Result<()> { + fn register(&mut self, _: PluginId, args: &Args, info: &Info) -> Result<()> { let plugin_args = PluginArgs::try_from(args)?; + self.target_name = Some(info.target_name.clone()); + self.tx = Arc::new(Mutex::new(Some(UnixStream::connect( plugin_args.socket_path, )?))); @@ -447,7 +508,7 @@ impl Register for Tracer { self.log_mem = plugin_args.log_mem; self.log_syscalls = plugin_args.log_syscalls; - #[cfg(any(feature = "plugin-api-v2", feature = "plugin-api-v3"))] + #[cfg(not(feature = "plugin-api-v1"))] { self.log_registers = plugin_args.log_registers; } diff --git a/qemu-plugin-sys/Cargo.toml b/qemu-plugin-sys/Cargo.toml index 1868666..4c3ce42 100644 --- a/qemu-plugin-sys/Cargo.toml +++ b/qemu-plugin-sys/Cargo.toml @@ -18,10 +18,12 @@ anyhow = "1.0.86" non_snake_case = "allow" [features] -default = ["plugin-api-v2"] +default = ["plugin-api-v4"] # Use the V1 plugin API, which is defined for versions below 9.0.0 plugin-api-v1 = [] # Use the V2 plugin API, which is defined for version 9.0.0 plugin-api-v2 = [] -# Use the V3 plugin API, which is defined for versions above 9.0.0 +# Use the V3 plugin API, which is defined for version 9.1.0 plugin-api-v3 = [] +# Use the V4 plugin API, which is defined for versions above 9.2.0 +plugin-api-v4 = [] diff --git a/qemu-plugin-sys/generate-bindings.rs b/qemu-plugin-sys/generate-bindings.rs index 335e44c..2d7befd 100755 --- a/qemu-plugin-sys/generate-bindings.rs +++ b/qemu-plugin-sys/generate-bindings.rs @@ -8,8 +8,6 @@ bindgen = "*" cargo_metadata = "*" # pkg-config = "*" reqwest = { version = "*", features = ["blocking"] } -tar = "*" -xz2 = "*" zip = "*" [lints.rust] non_snake_case = "allow" @@ -23,32 +21,27 @@ use bindgen::{ use cargo_metadata::MetadataCommand; use reqwest::blocking::get; use std::{ + io::copy, fs::{create_dir_all, read_to_string, write, File, OpenOptions}, - path::Path, + path::{Path, PathBuf}, }; -use tar::Archive; -use xz2::read::XzDecoder; use zip::ZipArchive; const QEMU_GITHUB_URL_BASE: &str = "https://github.com/qemu/qemu/"; -const QEMU_SRC_URL_BASE: &str = "https://download.qemu.org/"; -// Plugin V1 is from introduction to 8.2.4 -const QEMU_VERSION_V1: &str = "8.2.4"; -// Plugin V2 is from 9.0.0 -const QEMU_VERSION_V2: &str = "9.0.0"; -/// Plugin V3 is from 7de77d37880d7267a491cb32a1b2232017d1e545 -const QEMU_VERSION_V3: &str = "7de77d37880d7267a491cb32a1b2232017d1e545"; -fn qemu_src_url_v1() -> String { - format!("{}qemu-{}.tar.xz", QEMU_SRC_URL_BASE, QEMU_VERSION_V1) -} - -fn qemu_src_url_v2() -> String { - format!("{}qemu-{}.tar.xz", QEMU_SRC_URL_BASE, QEMU_VERSION_V2) -} - -fn qemu_src_url_v3() -> String { - format!("{}/archive/{}.zip", QEMU_GITHUB_URL_BASE, QEMU_VERSION_V3) +const QEMU_VERSIONS: &[&str] = &[ + // Plugin V1 is up until 8.2.4 + "1332b8dd434674480f0feb2cdf3bbaebb85b4240", + // Plugin V2 is from 9.0.0 + "c25df57ae8f9fe1c72eee2dab37d76d904ac382e", + // Plugin V3 is from 9.1.0 + "7de77d37880d7267a491cb32a1b2232017d1e545", + // Plugin V4 is from 9.2.0 + "595cd9ce2ec9330882c991a647d5bc2a5640f380", +]; + +fn qemu_git_url(hash: &str) -> String { + format!("{}/archive/{}.zip", QEMU_GITHUB_URL_BASE, hash) } /// Download a URL to a destination, using a blocking request @@ -63,43 +56,39 @@ fn download(url: &str, destination: &Path) -> Result<()> { Ok(()) } -/// Extract a tar.xz archive at a path to a destination -fn extract_txz(archive: &Path, destination: &Path) -> Result<()> { - let mut archive = File::open(archive)?; - let mut archive = XzDecoder::new(&mut archive); - let mut archive = Archive::new(&mut archive); - // Unpack archive, removing 1 leading path component - archive - .entries()? - .filter_map(|e| e.ok()) - .try_for_each(|mut e| { - let Ok(path) = e.path() else { - return Err(anyhow!("Failed to get path from archive entry")); - }; - let Some(prefix) = path.components().next() else { - return Err(anyhow!("Failed to get prefix from archive entry {path:?}")); - }; - let Ok(suffix) = path.strip_prefix(prefix) else { - return Err(anyhow!( - "Failed to strip prefix {prefix:?} from archive entry {path:?}" - )); - }; - e.unpack(destination.join(suffix)) - .map(|_| ()) - .map_err(|e| anyhow!(e)) - })?; - Ok(()) -} - -/// Extract a zip file at a path to a destination +/// Extract a zip file at a path to a destination (stripping the root) fn extract_zip(archive: &Path, destination: &Path) -> Result<()> { let archive = File::open(archive)?; let mut archive = ZipArchive::new(archive)?; - archive.extract(destination)?; + + for i in 0..archive.len() { + let mut file = archive.by_index(i)?; + let file_path = file.mangled_name(); + + let components: Vec<_> = file_path.components().collect(); + + if components.len() <= 1 { + continue; + } + + let new_path = components[1..].iter().collect::(); + let out_path = destination.join(new_path); + + if file.is_dir() { + create_dir_all(&out_path)?; + } else { + if let Some(parent) = out_path.parent() { + create_dir_all(parent)?; + } + let mut out_file = File::create(&out_path)?; + copy(&mut file, &mut out_file)?; + } + } Ok(()) } fn generate_windows_delaylink_library(qemu_plugin_symbols: &Path, destination: &Path) -> Result<()> { + println!("Generating Windows delaylink library from {:?} to {:?}", qemu_plugin_symbols, destination); let all_commands = read_to_string(qemu_plugin_symbols)?; let all_commands = all_commands.replace(|x| "{};".contains(x), ""); write(destination, format!("EXPORTS\n{all_commands}"))?; @@ -497,6 +486,35 @@ fn generate_bindings(qemu_plugin_header: &Path, destination: &Path) -> Result<() Ok(()) } +fn generate(tmp_dir: &Path, out_dir: &Path, version: usize) -> Result<()> { + println!("Generating bindings with tmp={:?} out={:?} version={}", tmp_dir, out_dir, version); + let src_archive = tmp_dir.join(format!("qemu-{}.zip", QEMU_VERSIONS[version - 1])); + let src_dir = tmp_dir.join(format!("qemu-{}", QEMU_VERSIONS[version - 1])); + + if !src_archive.exists() { + let qemu_url = qemu_git_url(QEMU_VERSIONS[version - 1]); + println!("Downloading {} to {:?}", qemu_url, src_archive); + download(&qemu_url, &src_archive)?; + } + + if !src_dir.exists() { + println!("Extracting {:?} to {:?}", src_archive, src_dir); + extract_zip(&src_archive, &src_dir)?; + } + + generate_windows_delaylink_library( + &src_dir.join("plugins").join("qemu-plugins.symbols"), + &out_dir.join(&format!("qemu_plugin_api_v{}.def", version)), + )?; + + generate_bindings( + &src_dir.join("include").join("qemu").join("qemu-plugin.h"), + &out_dir.join(&format!("bindings_v{}.rs", version)), + )?; + + Ok(()) +} + fn main() -> Result<()> { let metadata = MetadataCommand::new().no_deps().exec()?; @@ -519,71 +537,10 @@ fn main() -> Result<()> { create_dir_all(&tmp_dir)?; } - let src_archive_v1 = tmp_dir.join(format!("qemu-{}.tar.xz", QEMU_VERSION_V1)); - let src_dir_v1 = tmp_dir.join(format!("qemu-{}", QEMU_VERSION_V1)); - - if !src_archive_v1.exists() { - download(&qemu_src_url_v1(), &src_archive_v1)?; - } - - if !src_dir_v1.exists() { - extract_txz(&src_archive_v1, &src_dir_v1)?; - } - - let src_archive_v2 = tmp_dir.join(format!("qemu-{}.tar.xz", QEMU_VERSION_V2)); - let src_dir_v2 = tmp_dir.join(format!("qemu-{}", QEMU_VERSION_V2)); - - if !src_archive_v2.exists() { - download(&qemu_src_url_v2(), &src_archive_v2)?; - } - - if !src_dir_v2.exists() { - extract_txz(&src_archive_v2, &src_dir_v2)?; - } - - let src_archive_v3 = tmp_dir.join(format!("qemu-{}.zip", QEMU_VERSION_V3)); - let src_dir_v3 = tmp_dir.join(format!("qemu-{}", QEMU_VERSION_V3)); - - if !src_archive_v3.exists() { - download(&qemu_src_url_v3(), &src_archive_v3)?; - } - - if !src_dir_v3.exists() { - // NOTE: ZipArchive::extract extracts into the directory given a directory named - // the same as the ZIP file. - extract_zip(&src_archive_v3, &tmp_dir)?; - } - - generate_windows_delaylink_library( - &src_dir_v1.join("plugins").join("qemu-plugins.symbols"), - &out_dir.join("qemu_plugin_api_v1.def"), - )?; - - generate_windows_delaylink_library( - &src_dir_v2.join("plugins").join("qemu-plugins.symbols"), - &out_dir.join("qemu_plugin_api_v2.def"), - )?; - - generate_windows_delaylink_library( - &src_dir_v3.join("plugins").join("qemu-plugins.symbols"), - &out_dir.join("qemu_plugin_api_v3.def"), - )?; - - - generate_bindings( - &src_dir_v1.join("include").join("qemu").join("qemu-plugin.h"), - &out_dir.join("bindings_v1.rs"), - )?; - - generate_bindings( - &src_dir_v2.join("include").join("qemu").join("qemu-plugin.h"), - &out_dir.join("bindings_v2.rs"), - )?; - - generate_bindings( - &src_dir_v3.join("include").join("qemu").join("qemu-plugin.h"), - &out_dir.join("bindings_v3.rs"), - )?; + generate(&tmp_dir, &out_dir, 1)?; + generate(&tmp_dir, &out_dir, 2)?; + generate(&tmp_dir, &out_dir, 3)?; + generate(&tmp_dir, &out_dir, 4)?; Ok(()) } diff --git a/qemu-plugin-sys/src/bindings_v1.rs b/qemu-plugin-sys/src/bindings_v1.rs index c136161..1bf0f55 100644 --- a/qemu-plugin-sys/src/bindings_v1.rs +++ b/qemu-plugin-sys/src/bindings_v1.rs @@ -1,7 +1,9 @@ -/* automatically generated by rust-bindgen 0.69.4 */ +/* automatically generated by rust-bindgen 0.70.1 */ pub const __SYSCALL_WORDSIZE: u32 = 64; +pub const __USE_TIME_BITS64: u32 = 1; pub const __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64: u32 = 1; +pub const _BITS_STDINT_LEAST_H: u32 = 1; pub const QEMU_PLUGIN_VERSION: u32 = 1; #[repr(C)] #[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] diff --git a/qemu-plugin-sys/src/bindings_v2.rs b/qemu-plugin-sys/src/bindings_v2.rs index 44e5517..29bdfb2 100644 --- a/qemu-plugin-sys/src/bindings_v2.rs +++ b/qemu-plugin-sys/src/bindings_v2.rs @@ -1,7 +1,9 @@ -/* automatically generated by rust-bindgen 0.69.4 */ +/* automatically generated by rust-bindgen 0.70.1 */ pub const __SYSCALL_WORDSIZE: u32 = 64; +pub const __USE_TIME_BITS64: u32 = 1; pub const __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64: u32 = 1; +pub const _BITS_STDINT_LEAST_H: u32 = 1; pub const QEMU_PLUGIN_VERSION: u32 = 2; #[repr(C)] #[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] diff --git a/qemu-plugin-sys/src/bindings_v3.rs b/qemu-plugin-sys/src/bindings_v3.rs index 3d09443..988b509 100644 --- a/qemu-plugin-sys/src/bindings_v3.rs +++ b/qemu-plugin-sys/src/bindings_v3.rs @@ -1,7 +1,9 @@ -/* automatically generated by rust-bindgen 0.69.4 */ +/* automatically generated by rust-bindgen 0.70.1 */ pub const __SYSCALL_WORDSIZE: u32 = 64; +pub const __USE_TIME_BITS64: u32 = 1; pub const __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64: u32 = 1; +pub const _BITS_STDINT_LEAST_H: u32 = 1; pub const QEMU_PLUGIN_VERSION: u32 = 3; #[repr(C)] #[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] diff --git a/qemu-plugin-sys/src/bindings_v4.rs b/qemu-plugin-sys/src/bindings_v4.rs new file mode 100644 index 0000000..b666b6d --- /dev/null +++ b/qemu-plugin-sys/src/bindings_v4.rs @@ -0,0 +1,613 @@ +/* automatically generated by rust-bindgen 0.70.1 */ + +pub const __SYSCALL_WORDSIZE: u32 = 64; +pub const __USE_TIME_BITS64: u32 = 1; +pub const __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64: u32 = 1; +pub const _BITS_STDINT_LEAST_H: u32 = 1; +pub const QEMU_PLUGIN_VERSION: u32 = 4; +#[repr(C)] +#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] +pub struct GArray { + pub data: *mut ::std::os::raw::c_char, + pub len: ::std::os::raw::c_uint, +} +impl Default for GArray { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[repr(C)] +#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] +pub struct GByteArray { + pub data: *mut ::std::os::raw::c_uchar, + pub len: ::std::os::raw::c_uint, +} +impl Default for GByteArray { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[doc = " typedef qemu_plugin_id_t - Unique plugin ID"] +pub type qemu_plugin_id_t = u64; +#[doc = " struct qemu_info_t - system information for plugins\n\n This structure provides for some limited information about the\n system to allow the plugin to make decisions on how to proceed. For\n example it might only be suitable for running on some guest\n architectures or when under full system emulation."] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct qemu_info_t { + #[doc = " @target_name: string describing architecture"] + pub target_name: *const ::std::os::raw::c_char, + pub version: qemu_info_t__bindgen_ty_1, + #[doc = " @system_emulation: is this a full system emulation?"] + pub system_emulation: bool, + pub __bindgen_anon_1: qemu_info_t__bindgen_ty_2, +} +#[doc = " @version: minimum and current plugin API level"] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] +pub struct qemu_info_t__bindgen_ty_1 { + pub min: ::std::os::raw::c_int, + pub cur: ::std::os::raw::c_int, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union qemu_info_t__bindgen_ty_2 { + pub system: qemu_info_t__bindgen_ty_2__bindgen_ty_1, +} +#[doc = " @system: information relevant to system emulation"] +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] +pub struct qemu_info_t__bindgen_ty_2__bindgen_ty_1 { + #[doc = " @system.smp_vcpus: initial number of vCPUs"] + pub smp_vcpus: ::std::os::raw::c_int, + #[doc = " @system.max_vcpus: maximum possible number of vCPUs"] + pub max_vcpus: ::std::os::raw::c_int, +} +impl Default for qemu_info_t__bindgen_ty_2 { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +impl Default for qemu_info_t { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[doc = " typedef qemu_plugin_simple_cb_t - simple callback\n @id: the unique qemu_plugin_id_t\n\n This callback passes no information aside from the unique @id."] +pub type qemu_plugin_simple_cb_t = + ::std::option::Option; +#[doc = " typedef qemu_plugin_udata_cb_t - callback with user data\n @id: the unique qemu_plugin_id_t\n @userdata: a pointer to some user data supplied when the callback\n was registered."] +pub type qemu_plugin_udata_cb_t = ::std::option::Option< + unsafe extern "C" fn(id: qemu_plugin_id_t, userdata: *mut ::std::os::raw::c_void), +>; +#[doc = " typedef qemu_plugin_vcpu_simple_cb_t - vcpu callback\n @id: the unique qemu_plugin_id_t\n @vcpu_index: the current vcpu context"] +pub type qemu_plugin_vcpu_simple_cb_t = ::std::option::Option< + unsafe extern "C" fn(id: qemu_plugin_id_t, vcpu_index: ::std::os::raw::c_uint), +>; +#[doc = " typedef qemu_plugin_vcpu_udata_cb_t - vcpu callback\n @vcpu_index: the current vcpu context\n @userdata: a pointer to some user data supplied when the callback\n was registered."] +pub type qemu_plugin_vcpu_udata_cb_t = ::std::option::Option< + unsafe extern "C" fn(vcpu_index: ::std::os::raw::c_uint, userdata: *mut ::std::os::raw::c_void), +>; +extern "C" { + #[doc = " qemu_plugin_uninstall() - Uninstall a plugin\n @id: this plugin's opaque ID\n @cb: callback to be called once the plugin has been removed\n\n Do NOT assume that the plugin has been uninstalled once this function\n returns. Plugins are uninstalled asynchronously, and therefore the given\n plugin receives callbacks until @cb is called.\n\n Note: Calling this function from qemu_plugin_install() is a bug."] + pub fn qemu_plugin_uninstall(id: qemu_plugin_id_t, cb: qemu_plugin_simple_cb_t); +} +extern "C" { + #[doc = " qemu_plugin_reset() - Reset a plugin\n @id: this plugin's opaque ID\n @cb: callback to be called once the plugin has been reset\n\n Unregisters all callbacks for the plugin given by @id.\n\n Do NOT assume that the plugin has been reset once this function returns.\n Plugins are reset asynchronously, and therefore the given plugin receives\n callbacks until @cb is called."] + pub fn qemu_plugin_reset(id: qemu_plugin_id_t, cb: qemu_plugin_simple_cb_t); +} +extern "C" { + #[doc = " qemu_plugin_register_vcpu_init_cb() - register a vCPU initialization callback\n @id: plugin ID\n @cb: callback function\n\n The @cb function is called every time a vCPU is initialized.\n\n See also: qemu_plugin_register_vcpu_exit_cb()"] + pub fn qemu_plugin_register_vcpu_init_cb( + id: qemu_plugin_id_t, + cb: qemu_plugin_vcpu_simple_cb_t, + ); +} +extern "C" { + #[doc = " qemu_plugin_register_vcpu_exit_cb() - register a vCPU exit callback\n @id: plugin ID\n @cb: callback function\n\n The @cb function is called every time a vCPU exits.\n\n See also: qemu_plugin_register_vcpu_init_cb()"] + pub fn qemu_plugin_register_vcpu_exit_cb( + id: qemu_plugin_id_t, + cb: qemu_plugin_vcpu_simple_cb_t, + ); +} +extern "C" { + #[doc = " qemu_plugin_register_vcpu_idle_cb() - register a vCPU idle callback\n @id: plugin ID\n @cb: callback function\n\n The @cb function is called every time a vCPU idles."] + pub fn qemu_plugin_register_vcpu_idle_cb( + id: qemu_plugin_id_t, + cb: qemu_plugin_vcpu_simple_cb_t, + ); +} +extern "C" { + #[doc = " qemu_plugin_register_vcpu_resume_cb() - register a vCPU resume callback\n @id: plugin ID\n @cb: callback function\n\n The @cb function is called every time a vCPU resumes execution."] + pub fn qemu_plugin_register_vcpu_resume_cb( + id: qemu_plugin_id_t, + cb: qemu_plugin_vcpu_simple_cb_t, + ); +} +#[doc = " struct qemu_plugin_tb - Opaque handle for a translation block"] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct qemu_plugin_tb { + _unused: [u8; 0], +} +#[doc = " struct qemu_plugin_insn - Opaque handle for a translated instruction"] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct qemu_plugin_insn { + _unused: [u8; 0], +} +#[doc = " struct qemu_plugin_scoreboard - Opaque handle for a scoreboard"] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct qemu_plugin_scoreboard { + _unused: [u8; 0], +} +#[doc = " typedef qemu_plugin_u64 - uint64_t member of an entry in a scoreboard\n\n This field allows to access a specific uint64_t member in one given entry,\n located at a specified offset. Inline operations expect this as entry."] +#[repr(C)] +#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] +pub struct qemu_plugin_u64 { + pub score: *mut qemu_plugin_scoreboard, + pub offset: usize, +} +impl Default for qemu_plugin_u64 { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[repr(u32)] +#[doc = " enum qemu_plugin_cb_flags - type of callback\n\n @QEMU_PLUGIN_CB_NO_REGS: callback does not access the CPU's regs\n @QEMU_PLUGIN_CB_R_REGS: callback reads the CPU's regs\n @QEMU_PLUGIN_CB_RW_REGS: callback reads and writes the CPU's regs\n\n Note: currently QEMU_PLUGIN_CB_RW_REGS is unused, plugins cannot change\n system register state."] +#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] +pub enum qemu_plugin_cb_flags { + QEMU_PLUGIN_CB_NO_REGS = 0, + QEMU_PLUGIN_CB_R_REGS = 1, + QEMU_PLUGIN_CB_RW_REGS = 2, +} +#[repr(u32)] +#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] +pub enum qemu_plugin_mem_rw { + QEMU_PLUGIN_MEM_R = 1, + QEMU_PLUGIN_MEM_W = 2, + QEMU_PLUGIN_MEM_RW = 3, +} +#[repr(u32)] +#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] +pub enum qemu_plugin_mem_value_type { + QEMU_PLUGIN_MEM_VALUE_U8 = 0, + QEMU_PLUGIN_MEM_VALUE_U16 = 1, + QEMU_PLUGIN_MEM_VALUE_U32 = 2, + QEMU_PLUGIN_MEM_VALUE_U64 = 3, + QEMU_PLUGIN_MEM_VALUE_U128 = 4, +} +#[doc = " typedef qemu_plugin_mem_value - value accessed during a load/store"] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct qemu_plugin_mem_value { + pub type_: qemu_plugin_mem_value_type, + pub data: qemu_plugin_mem_value__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union qemu_plugin_mem_value__bindgen_ty_1 { + pub u8_: u8, + pub u16_: u16, + pub u32_: u32, + pub u64_: u64, + pub u128_: qemu_plugin_mem_value__bindgen_ty_1__bindgen_ty_1, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] +pub struct qemu_plugin_mem_value__bindgen_ty_1__bindgen_ty_1 { + pub low: u64, + pub high: u64, +} +impl Default for qemu_plugin_mem_value__bindgen_ty_1 { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +impl Default for qemu_plugin_mem_value { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[repr(u32)] +#[doc = " enum qemu_plugin_cond - condition to enable callback\n\n @QEMU_PLUGIN_COND_NEVER: false\n @QEMU_PLUGIN_COND_ALWAYS: true\n @QEMU_PLUGIN_COND_EQ: is equal?\n @QEMU_PLUGIN_COND_NE: is not equal?\n @QEMU_PLUGIN_COND_LT: is less than?\n @QEMU_PLUGIN_COND_LE: is less than or equal?\n @QEMU_PLUGIN_COND_GT: is greater than?\n @QEMU_PLUGIN_COND_GE: is greater than or equal?"] +#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] +pub enum qemu_plugin_cond { + QEMU_PLUGIN_COND_NEVER = 0, + QEMU_PLUGIN_COND_ALWAYS = 1, + QEMU_PLUGIN_COND_EQ = 2, + QEMU_PLUGIN_COND_NE = 3, + QEMU_PLUGIN_COND_LT = 4, + QEMU_PLUGIN_COND_LE = 5, + QEMU_PLUGIN_COND_GT = 6, + QEMU_PLUGIN_COND_GE = 7, +} +#[doc = " typedef qemu_plugin_vcpu_tb_trans_cb_t - translation callback\n @id: unique plugin id\n @tb: opaque handle used for querying and instrumenting a block."] +pub type qemu_plugin_vcpu_tb_trans_cb_t = + ::std::option::Option; +extern "C" { + #[doc = " qemu_plugin_register_vcpu_tb_trans_cb() - register a translate cb\n @id: plugin ID\n @cb: callback function\n\n The @cb function is called every time a translation occurs. The @cb\n function is passed an opaque qemu_plugin_type which it can query\n for additional information including the list of translated\n instructions. At this point the plugin can register further\n callbacks to be triggered when the block or individual instruction\n executes."] + pub fn qemu_plugin_register_vcpu_tb_trans_cb( + id: qemu_plugin_id_t, + cb: qemu_plugin_vcpu_tb_trans_cb_t, + ); +} +extern "C" { + #[doc = " qemu_plugin_register_vcpu_tb_exec_cb() - register execution callback\n @tb: the opaque qemu_plugin_tb handle for the translation\n @cb: callback function\n @flags: does the plugin read or write the CPU's registers?\n @userdata: any plugin data to pass to the @cb?\n\n The @cb function is called every time a translated unit executes."] + pub fn qemu_plugin_register_vcpu_tb_exec_cb( + tb: *mut qemu_plugin_tb, + cb: qemu_plugin_vcpu_udata_cb_t, + flags: qemu_plugin_cb_flags, + userdata: *mut ::std::os::raw::c_void, + ); +} +extern "C" { + #[doc = " qemu_plugin_register_vcpu_tb_exec_cond_cb() - register conditional callback\n @tb: the opaque qemu_plugin_tb handle for the translation\n @cb: callback function\n @cond: condition to enable callback\n @entry: first operand for condition\n @imm: second operand for condition\n @flags: does the plugin read or write the CPU's registers?\n @userdata: any plugin data to pass to the @cb?\n\n The @cb function is called when a translated unit executes if\n entry @cond imm is true.\n If condition is QEMU_PLUGIN_COND_ALWAYS, condition is never interpreted and\n this function is equivalent to qemu_plugin_register_vcpu_tb_exec_cb.\n If condition QEMU_PLUGIN_COND_NEVER, condition is never interpreted and\n callback is never installed."] + pub fn qemu_plugin_register_vcpu_tb_exec_cond_cb( + tb: *mut qemu_plugin_tb, + cb: qemu_plugin_vcpu_udata_cb_t, + flags: qemu_plugin_cb_flags, + cond: qemu_plugin_cond, + entry: qemu_plugin_u64, + imm: u64, + userdata: *mut ::std::os::raw::c_void, + ); +} +#[repr(u32)] +#[doc = " enum qemu_plugin_op - describes an inline op\n\n @QEMU_PLUGIN_INLINE_ADD_U64: add an immediate value uint64_t\n @QEMU_PLUGIN_INLINE_STORE_U64: store an immediate value uint64_t"] +#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] +pub enum qemu_plugin_op { + QEMU_PLUGIN_INLINE_ADD_U64 = 0, + QEMU_PLUGIN_INLINE_STORE_U64 = 1, +} +extern "C" { + #[doc = " qemu_plugin_register_vcpu_tb_exec_inline_per_vcpu() - execution inline op\n @tb: the opaque qemu_plugin_tb handle for the translation\n @op: the type of qemu_plugin_op (e.g. ADD_U64)\n @entry: entry to run op\n @imm: the op data (e.g. 1)\n\n Insert an inline op on a given scoreboard entry."] + pub fn qemu_plugin_register_vcpu_tb_exec_inline_per_vcpu( + tb: *mut qemu_plugin_tb, + op: qemu_plugin_op, + entry: qemu_plugin_u64, + imm: u64, + ); +} +extern "C" { + #[doc = " qemu_plugin_register_vcpu_insn_exec_cb() - register insn execution cb\n @insn: the opaque qemu_plugin_insn handle for an instruction\n @cb: callback function\n @flags: does the plugin read or write the CPU's registers?\n @userdata: any plugin data to pass to the @cb?\n\n The @cb function is called every time an instruction is executed"] + pub fn qemu_plugin_register_vcpu_insn_exec_cb( + insn: *mut qemu_plugin_insn, + cb: qemu_plugin_vcpu_udata_cb_t, + flags: qemu_plugin_cb_flags, + userdata: *mut ::std::os::raw::c_void, + ); +} +extern "C" { + #[doc = " qemu_plugin_register_vcpu_insn_exec_cond_cb() - conditional insn execution cb\n @insn: the opaque qemu_plugin_insn handle for an instruction\n @cb: callback function\n @flags: does the plugin read or write the CPU's registers?\n @cond: condition to enable callback\n @entry: first operand for condition\n @imm: second operand for condition\n @userdata: any plugin data to pass to the @cb?\n\n The @cb function is called when an instruction executes if\n entry @cond imm is true.\n If condition is QEMU_PLUGIN_COND_ALWAYS, condition is never interpreted and\n this function is equivalent to qemu_plugin_register_vcpu_insn_exec_cb.\n If condition QEMU_PLUGIN_COND_NEVER, condition is never interpreted and\n callback is never installed."] + pub fn qemu_plugin_register_vcpu_insn_exec_cond_cb( + insn: *mut qemu_plugin_insn, + cb: qemu_plugin_vcpu_udata_cb_t, + flags: qemu_plugin_cb_flags, + cond: qemu_plugin_cond, + entry: qemu_plugin_u64, + imm: u64, + userdata: *mut ::std::os::raw::c_void, + ); +} +extern "C" { + #[doc = " qemu_plugin_register_vcpu_insn_exec_inline_per_vcpu() - insn exec inline op\n @insn: the opaque qemu_plugin_insn handle for an instruction\n @op: the type of qemu_plugin_op (e.g. ADD_U64)\n @entry: entry to run op\n @imm: the op data (e.g. 1)\n\n Insert an inline op to every time an instruction executes."] + pub fn qemu_plugin_register_vcpu_insn_exec_inline_per_vcpu( + insn: *mut qemu_plugin_insn, + op: qemu_plugin_op, + entry: qemu_plugin_u64, + imm: u64, + ); +} +extern "C" { + #[doc = " qemu_plugin_tb_n_insns() - query helper for number of insns in TB\n @tb: opaque handle to TB passed to callback\n\n Returns: number of instructions in this block"] + pub fn qemu_plugin_tb_n_insns(tb: *const qemu_plugin_tb) -> usize; +} +extern "C" { + #[doc = " qemu_plugin_tb_vaddr() - query helper for vaddr of TB start\n @tb: opaque handle to TB passed to callback\n\n Returns: virtual address of block start"] + pub fn qemu_plugin_tb_vaddr(tb: *const qemu_plugin_tb) -> u64; +} +extern "C" { + #[doc = " qemu_plugin_tb_get_insn() - retrieve handle for instruction\n @tb: opaque handle to TB passed to callback\n @idx: instruction number, 0 indexed\n\n The returned handle can be used in follow up helper queries as well\n as when instrumenting an instruction. It is only valid for the\n lifetime of the callback.\n\n Returns: opaque handle to instruction"] + pub fn qemu_plugin_tb_get_insn(tb: *const qemu_plugin_tb, idx: usize) -> *mut qemu_plugin_insn; +} +extern "C" { + #[doc = " qemu_plugin_insn_data() - copy instruction data\n @insn: opaque instruction handle from qemu_plugin_tb_get_insn()\n @dest: destination into which data is copied\n @len: length of dest\n\n Returns the number of bytes copied, minimum of @len and insn size."] + pub fn qemu_plugin_insn_data( + insn: *const qemu_plugin_insn, + dest: *mut ::std::os::raw::c_void, + len: usize, + ) -> usize; +} +extern "C" { + #[doc = " qemu_plugin_insn_size() - return size of instruction\n @insn: opaque instruction handle from qemu_plugin_tb_get_insn()\n\n Returns: size of instruction in bytes"] + pub fn qemu_plugin_insn_size(insn: *const qemu_plugin_insn) -> usize; +} +extern "C" { + #[doc = " qemu_plugin_insn_vaddr() - return vaddr of instruction\n @insn: opaque instruction handle from qemu_plugin_tb_get_insn()\n\n Returns: virtual address of instruction"] + pub fn qemu_plugin_insn_vaddr(insn: *const qemu_plugin_insn) -> u64; +} +extern "C" { + #[doc = " qemu_plugin_insn_haddr() - return hardware addr of instruction\n @insn: opaque instruction handle from qemu_plugin_tb_get_insn()\n\n Returns: hardware (physical) target address of instruction"] + pub fn qemu_plugin_insn_haddr(insn: *const qemu_plugin_insn) -> *mut ::std::os::raw::c_void; +} +#[doc = " typedef qemu_plugin_meminfo_t - opaque memory transaction handle\n\n This can be further queried using the qemu_plugin_mem_* query\n functions."] +pub type qemu_plugin_meminfo_t = u32; +#[doc = " struct qemu_plugin_hwaddr - opaque hw address handle"] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct qemu_plugin_hwaddr { + _unused: [u8; 0], +} +extern "C" { + #[doc = " qemu_plugin_mem_size_shift() - get size of access\n @info: opaque memory transaction handle\n\n Returns: size of access in ^2 (0=byte, 1=16bit, 2=32bit etc...)"] + pub fn qemu_plugin_mem_size_shift(info: qemu_plugin_meminfo_t) -> ::std::os::raw::c_uint; +} +extern "C" { + #[doc = " qemu_plugin_mem_is_sign_extended() - was the access sign extended\n @info: opaque memory transaction handle\n\n Returns: true if it was, otherwise false"] + pub fn qemu_plugin_mem_is_sign_extended(info: qemu_plugin_meminfo_t) -> bool; +} +extern "C" { + #[doc = " qemu_plugin_mem_is_big_endian() - was the access big endian\n @info: opaque memory transaction handle\n\n Returns: true if it was, otherwise false"] + pub fn qemu_plugin_mem_is_big_endian(info: qemu_plugin_meminfo_t) -> bool; +} +extern "C" { + #[doc = " qemu_plugin_mem_is_store() - was the access a store\n @info: opaque memory transaction handle\n\n Returns: true if it was, otherwise false"] + pub fn qemu_plugin_mem_is_store(info: qemu_plugin_meminfo_t) -> bool; +} +extern "C" { + #[doc = " qemu_plugin_mem_get_mem_value() - return last value loaded/stored\n @info: opaque memory transaction handle\n\n Returns: memory value"] + pub fn qemu_plugin_mem_get_value(info: qemu_plugin_meminfo_t) -> qemu_plugin_mem_value; +} +extern "C" { + #[doc = " qemu_plugin_get_hwaddr() - return handle for memory operation\n @info: opaque memory info structure\n @vaddr: the virtual address of the memory operation\n\n For system emulation returns a qemu_plugin_hwaddr handle to query\n details about the actual physical address backing the virtual\n address. For linux-user guests it just returns NULL.\n\n This handle is *only* valid for the duration of the callback. Any\n information about the handle should be recovered before the\n callback returns."] + pub fn qemu_plugin_get_hwaddr( + info: qemu_plugin_meminfo_t, + vaddr: u64, + ) -> *mut qemu_plugin_hwaddr; +} +extern "C" { + #[doc = " qemu_plugin_hwaddr_is_io() - query whether memory operation is IO\n @haddr: address handle from qemu_plugin_get_hwaddr()\n\n Returns true if the handle's memory operation is to memory-mapped IO, or\n false if it is to RAM"] + pub fn qemu_plugin_hwaddr_is_io(haddr: *const qemu_plugin_hwaddr) -> bool; +} +extern "C" { + #[doc = " qemu_plugin_hwaddr_phys_addr() - query physical address for memory operation\n @haddr: address handle from qemu_plugin_get_hwaddr()\n\n Returns the physical address associated with the memory operation\n\n Note that the returned physical address may not be unique if you are dealing\n with multiple address spaces."] + pub fn qemu_plugin_hwaddr_phys_addr(haddr: *const qemu_plugin_hwaddr) -> u64; +} +extern "C" { + #[doc = " Returns a string representing the device. The string is valid for\n the lifetime of the plugin."] + pub fn qemu_plugin_hwaddr_device_name( + h: *const qemu_plugin_hwaddr, + ) -> *const ::std::os::raw::c_char; +} +#[doc = " typedef qemu_plugin_vcpu_mem_cb_t - memory callback function type\n @vcpu_index: the executing vCPU\n @info: an opaque handle for further queries about the memory\n @vaddr: the virtual address of the transaction\n @userdata: any user data attached to the callback"] +pub type qemu_plugin_vcpu_mem_cb_t = ::std::option::Option< + unsafe extern "C" fn( + vcpu_index: ::std::os::raw::c_uint, + info: qemu_plugin_meminfo_t, + vaddr: u64, + userdata: *mut ::std::os::raw::c_void, + ), +>; +extern "C" { + #[doc = " qemu_plugin_register_vcpu_mem_cb() - register memory access callback\n @insn: handle for instruction to instrument\n @cb: callback of type qemu_plugin_vcpu_mem_cb_t\n @flags: (currently unused) callback flags\n @rw: monitor reads, writes or both\n @userdata: opaque pointer for userdata\n\n This registers a full callback for every memory access generated by\n an instruction. If the instruction doesn't access memory no\n callback will be made.\n\n The callback reports the vCPU the access took place on, the virtual\n address of the access and a handle for further queries. The user\n can attach some userdata to the callback for additional purposes.\n\n Other execution threads will continue to execute during the\n callback so the plugin is responsible for ensuring it doesn't get\n confused by making appropriate use of locking if required."] + pub fn qemu_plugin_register_vcpu_mem_cb( + insn: *mut qemu_plugin_insn, + cb: qemu_plugin_vcpu_mem_cb_t, + flags: qemu_plugin_cb_flags, + rw: qemu_plugin_mem_rw, + userdata: *mut ::std::os::raw::c_void, + ); +} +extern "C" { + #[doc = " qemu_plugin_register_vcpu_mem_inline_per_vcpu() - inline op for mem access\n @insn: handle for instruction to instrument\n @rw: apply to reads, writes or both\n @op: the op, of type qemu_plugin_op\n @entry: entry to run op\n @imm: immediate data for @op\n\n This registers a inline op every memory access generated by the\n instruction."] + pub fn qemu_plugin_register_vcpu_mem_inline_per_vcpu( + insn: *mut qemu_plugin_insn, + rw: qemu_plugin_mem_rw, + op: qemu_plugin_op, + entry: qemu_plugin_u64, + imm: u64, + ); +} +extern "C" { + #[doc = " qemu_plugin_request_time_control() - request the ability to control time\n\n This grants the plugin the ability to control system time. Only one\n plugin can control time so if multiple plugins request the ability\n all but the first will fail.\n\n Returns an opaque handle or NULL if fails"] + pub fn qemu_plugin_request_time_control() -> *const ::std::os::raw::c_void; +} +extern "C" { + #[doc = " qemu_plugin_update_ns() - update system emulation time\n @handle: opaque handle returned by qemu_plugin_request_time_control()\n @time: time in nanoseconds\n\n This allows an appropriately authorised plugin (i.e. holding the\n time control handle) to move system time forward to @time. For\n user-mode emulation the time is not changed by this as all reported\n time comes from the host kernel.\n\n Start time is 0."] + pub fn qemu_plugin_update_ns(handle: *const ::std::os::raw::c_void, time: i64); +} +pub type qemu_plugin_vcpu_syscall_cb_t = ::std::option::Option< + unsafe extern "C" fn( + id: qemu_plugin_id_t, + vcpu_index: ::std::os::raw::c_uint, + num: i64, + a1: u64, + a2: u64, + a3: u64, + a4: u64, + a5: u64, + a6: u64, + a7: u64, + a8: u64, + ), +>; +extern "C" { + pub fn qemu_plugin_register_vcpu_syscall_cb( + id: qemu_plugin_id_t, + cb: qemu_plugin_vcpu_syscall_cb_t, + ); +} +pub type qemu_plugin_vcpu_syscall_ret_cb_t = ::std::option::Option< + unsafe extern "C" fn( + id: qemu_plugin_id_t, + vcpu_idx: ::std::os::raw::c_uint, + num: i64, + ret: i64, + ), +>; +extern "C" { + pub fn qemu_plugin_register_vcpu_syscall_ret_cb( + id: qemu_plugin_id_t, + cb: qemu_plugin_vcpu_syscall_ret_cb_t, + ); +} +extern "C" { + #[doc = " qemu_plugin_insn_disas() - return disassembly string for instruction\n @insn: instruction reference\n\n Returns an allocated string containing the disassembly"] + pub fn qemu_plugin_insn_disas(insn: *const qemu_plugin_insn) -> *mut ::std::os::raw::c_char; +} +extern "C" { + #[doc = " qemu_plugin_insn_symbol() - best effort symbol lookup\n @insn: instruction reference\n\n Return a static string referring to the symbol. This is dependent\n on the binary QEMU is running having provided a symbol table."] + pub fn qemu_plugin_insn_symbol(insn: *const qemu_plugin_insn) -> *const ::std::os::raw::c_char; +} +extern "C" { + #[doc = " qemu_plugin_vcpu_for_each() - iterate over the existing vCPU\n @id: plugin ID\n @cb: callback function\n\n The @cb function is called once for each existing vCPU.\n\n See also: qemu_plugin_register_vcpu_init_cb()"] + pub fn qemu_plugin_vcpu_for_each(id: qemu_plugin_id_t, cb: qemu_plugin_vcpu_simple_cb_t); +} +extern "C" { + pub fn qemu_plugin_register_flush_cb(id: qemu_plugin_id_t, cb: qemu_plugin_simple_cb_t); +} +extern "C" { + #[doc = " qemu_plugin_register_atexit_cb() - register exit callback\n @id: plugin ID\n @cb: callback\n @userdata: user data for callback\n\n The @cb function is called once execution has finished. Plugins\n should be able to free all their resources at this point much like\n after a reset/uninstall callback is called.\n\n In user-mode it is possible a few un-instrumented instructions from\n child threads may run before the host kernel reaps the threads."] + pub fn qemu_plugin_register_atexit_cb( + id: qemu_plugin_id_t, + cb: qemu_plugin_udata_cb_t, + userdata: *mut ::std::os::raw::c_void, + ); +} +extern "C" { + #[doc = " returns how many vcpus were started at this point"] + pub fn qemu_plugin_num_vcpus() -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " qemu_plugin_outs() - output string via QEMU's logging system\n @string: a string"] + pub fn qemu_plugin_outs(string: *const ::std::os::raw::c_char); +} +extern "C" { + #[doc = " qemu_plugin_bool_parse() - parses a boolean argument in the form of\n \"=[on|yes|true|off|no|false]\"\n\n @name: argument name, the part before the equals sign\n @val: argument value, what's after the equals sign\n @ret: output return value\n\n returns true if the combination @name=@val parses correctly to a boolean\n argument, and false otherwise"] + pub fn qemu_plugin_bool_parse( + name: *const ::std::os::raw::c_char, + val: *const ::std::os::raw::c_char, + ret: *mut bool, + ) -> bool; +} +extern "C" { + #[doc = " qemu_plugin_path_to_binary() - path to binary file being executed\n\n Return a string representing the path to the binary. For user-mode\n this is the main executable. For system emulation we currently\n return NULL. The user should g_free() the string once no longer\n needed."] + pub fn qemu_plugin_path_to_binary() -> *const ::std::os::raw::c_char; +} +extern "C" { + #[doc = " qemu_plugin_start_code() - returns start of text segment\n\n Returns the nominal start address of the main text segment in\n user-mode. Currently returns 0 for system emulation."] + pub fn qemu_plugin_start_code() -> u64; +} +extern "C" { + #[doc = " qemu_plugin_end_code() - returns end of text segment\n\n Returns the nominal end address of the main text segment in\n user-mode. Currently returns 0 for system emulation."] + pub fn qemu_plugin_end_code() -> u64; +} +extern "C" { + #[doc = " qemu_plugin_entry_code() - returns start address for module\n\n Returns the nominal entry address of the main text segment in\n user-mode. Currently returns 0 for system emulation."] + pub fn qemu_plugin_entry_code() -> u64; +} +#[doc = " struct qemu_plugin_register - Opaque handle for register access"] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct qemu_plugin_register { + _unused: [u8; 0], +} +#[doc = " typedef qemu_plugin_reg_descriptor - register descriptions\n\n @handle: opaque handle for retrieving value with qemu_plugin_read_register\n @name: register name\n @feature: optional feature descriptor, can be NULL"] +#[repr(C)] +#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] +pub struct qemu_plugin_reg_descriptor { + pub handle: *mut qemu_plugin_register, + pub name: *const ::std::os::raw::c_char, + pub feature: *const ::std::os::raw::c_char, +} +impl Default for qemu_plugin_reg_descriptor { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +extern "C" { + #[doc = " qemu_plugin_get_registers() - return register list for current vCPU\n\n Returns a potentially empty GArray of qemu_plugin_reg_descriptor.\n Caller frees the array (but not the const strings).\n\n Should be used from a qemu_plugin_register_vcpu_init_cb() callback\n after the vCPU is initialised, i.e. in the vCPU context."] + pub fn qemu_plugin_get_registers() -> *mut GArray; +} +extern "C" { + #[doc = " qemu_plugin_read_memory_vaddr() - read from memory using a virtual address\n\n @addr: A virtual address to read from\n @data: A byte array to store data into\n @len: The number of bytes to read, starting from @addr\n\n @len bytes of data is read starting at @addr and stored into @data. If @data\n is not large enough to hold @len bytes, it will be expanded to the necessary\n size, reallocating if necessary. @len must be greater than 0.\n\n This function does not ensure writes are flushed prior to reading, so\n callers should take care when calling this function in plugin callbacks to\n avoid attempting to read data which may not yet be written and should use\n the memory callback API instead.\n\n Returns true on success and false on failure."] + pub fn qemu_plugin_read_memory_vaddr(addr: u64, data: *mut GByteArray, len: usize) -> bool; +} +extern "C" { + #[doc = " qemu_plugin_read_register() - read register for current vCPU\n\n @handle: a @qemu_plugin_reg_handle handle\n @buf: A GByteArray for the data owned by the plugin\n\n This function is only available in a context that register read access is\n explicitly requested via the QEMU_PLUGIN_CB_R_REGS flag.\n\n Returns the size of the read register. The content of @buf is in target byte\n order. On failure returns -1."] + pub fn qemu_plugin_read_register( + handle: *mut qemu_plugin_register, + buf: *mut GByteArray, + ) -> ::std::os::raw::c_int; +} +extern "C" { + #[doc = " qemu_plugin_scoreboard_new() - alloc a new scoreboard\n\n @element_size: size (in bytes) for one entry\n\n Returns a pointer to a new scoreboard. It must be freed using\n qemu_plugin_scoreboard_free."] + pub fn qemu_plugin_scoreboard_new(element_size: usize) -> *mut qemu_plugin_scoreboard; +} +extern "C" { + #[doc = " qemu_plugin_scoreboard_free() - free a scoreboard\n @score: scoreboard to free"] + pub fn qemu_plugin_scoreboard_free(score: *mut qemu_plugin_scoreboard); +} +extern "C" { + #[doc = " qemu_plugin_scoreboard_find() - get pointer to an entry of a scoreboard\n @score: scoreboard to query\n @vcpu_index: entry index\n\n Returns address of entry of a scoreboard matching a given vcpu_index. This\n address can be modified later if scoreboard is resized."] + pub fn qemu_plugin_scoreboard_find( + score: *mut qemu_plugin_scoreboard, + vcpu_index: ::std::os::raw::c_uint, + ) -> *mut ::std::os::raw::c_void; +} +extern "C" { + #[doc = " qemu_plugin_u64_add() - add a value to a qemu_plugin_u64 for a given vcpu\n @entry: entry to query\n @vcpu_index: entry index\n @added: value to add"] + pub fn qemu_plugin_u64_add( + entry: qemu_plugin_u64, + vcpu_index: ::std::os::raw::c_uint, + added: u64, + ); +} +extern "C" { + #[doc = " qemu_plugin_u64_get() - get value of a qemu_plugin_u64 for a given vcpu\n @entry: entry to query\n @vcpu_index: entry index"] + pub fn qemu_plugin_u64_get(entry: qemu_plugin_u64, vcpu_index: ::std::os::raw::c_uint) -> u64; +} +extern "C" { + #[doc = " qemu_plugin_u64_set() - set value of a qemu_plugin_u64 for a given vcpu\n @entry: entry to query\n @vcpu_index: entry index\n @val: new value"] + pub fn qemu_plugin_u64_set( + entry: qemu_plugin_u64, + vcpu_index: ::std::os::raw::c_uint, + val: u64, + ); +} +extern "C" { + #[doc = " qemu_plugin_u64_sum() - return sum of all vcpu entries in a scoreboard\n @entry: entry to sum"] + pub fn qemu_plugin_u64_sum(entry: qemu_plugin_u64) -> u64; +} diff --git a/qemu-plugin-sys/src/lib.rs b/qemu-plugin-sys/src/lib.rs index bda3671..896624e 100644 --- a/qemu-plugin-sys/src/lib.rs +++ b/qemu-plugin-sys/src/lib.rs @@ -14,3 +14,6 @@ include!("bindings_v2.rs"); #[cfg(feature = "plugin-api-v3")] include!("bindings_v3.rs"); + +#[cfg(feature = "plugin-api-v4")] +include!("bindings_v4.rs"); diff --git a/qemu-plugin-sys/src/qemu_plugin_api_v4.def b/qemu-plugin-sys/src/qemu_plugin_api_v4.def new file mode 100644 index 0000000..f8f4d12 --- /dev/null +++ b/qemu-plugin-sys/src/qemu_plugin_api_v4.def @@ -0,0 +1,60 @@ +EXPORTS + + qemu_plugin_bool_parse + qemu_plugin_end_code + qemu_plugin_entry_code + qemu_plugin_get_hwaddr + qemu_plugin_get_registers + qemu_plugin_hwaddr_device_name + qemu_plugin_hwaddr_is_io + qemu_plugin_hwaddr_phys_addr + qemu_plugin_insn_data + qemu_plugin_insn_disas + qemu_plugin_insn_haddr + qemu_plugin_insn_size + qemu_plugin_insn_symbol + qemu_plugin_insn_vaddr + qemu_plugin_mem_get_value + qemu_plugin_mem_is_big_endian + qemu_plugin_mem_is_sign_extended + qemu_plugin_mem_is_store + qemu_plugin_mem_size_shift + qemu_plugin_num_vcpus + qemu_plugin_outs + qemu_plugin_path_to_binary + qemu_plugin_read_memory_vaddr + qemu_plugin_read_register + qemu_plugin_register_atexit_cb + qemu_plugin_register_flush_cb + qemu_plugin_register_vcpu_exit_cb + qemu_plugin_register_vcpu_idle_cb + qemu_plugin_register_vcpu_init_cb + qemu_plugin_register_vcpu_insn_exec_cb + qemu_plugin_register_vcpu_insn_exec_cond_cb + qemu_plugin_register_vcpu_insn_exec_inline_per_vcpu + qemu_plugin_register_vcpu_mem_cb + qemu_plugin_register_vcpu_mem_inline_per_vcpu + qemu_plugin_register_vcpu_resume_cb + qemu_plugin_register_vcpu_syscall_cb + qemu_plugin_register_vcpu_syscall_ret_cb + qemu_plugin_register_vcpu_tb_exec_cb + qemu_plugin_register_vcpu_tb_exec_cond_cb + qemu_plugin_register_vcpu_tb_exec_inline_per_vcpu + qemu_plugin_register_vcpu_tb_trans_cb + qemu_plugin_request_time_control + qemu_plugin_reset + qemu_plugin_scoreboard_free + qemu_plugin_scoreboard_find + qemu_plugin_scoreboard_new + qemu_plugin_start_code + qemu_plugin_tb_get_insn + qemu_plugin_tb_n_insns + qemu_plugin_tb_vaddr + qemu_plugin_u64_add + qemu_plugin_u64_get + qemu_plugin_u64_set + qemu_plugin_u64_sum + qemu_plugin_uninstall + qemu_plugin_update_ns + qemu_plugin_vcpu_for_each + diff --git a/qemu-plugin/Cargo.toml b/qemu-plugin/Cargo.toml index 1366bdc..77aaa2c 100644 --- a/qemu-plugin/Cargo.toml +++ b/qemu-plugin/Cargo.toml @@ -12,36 +12,33 @@ repository.workspace = true version.workspace = true [dependencies] -anyhow = "1.0.86" -once_cell = "1.19.0" -qemu-plugin-sys = { version = "9.0.0-v0", workspace = true, default-features = false } -thiserror = "1.0.61" +anyhow = "1.0.94" +once_cell = "1.20.2" +qemu-plugin-sys = { version = "9.1.2-v0", workspace = true, default-features = false } +thiserror = "2.0.4" num-traits = { version = "0.2.19", optional = true } -[target.'cfg(windows)'.dependencies.libloading] -version = "0.8.3" -[target.'cfg(windows)'.dependencies.lazy_static] -version = "1.4" - -[target.'cfg(windows)'.dependencies.windows] -version = "0.56.0" -features = [ +[target.'cfg(windows)'.dependencies] +windows = { version = "0.58.0", features = [ "Win32_System_WindowsProgramming", "Win32_System_LibraryLoader", "Win32_Foundation", -] +] } -[target.'cfg(windows)'.dependencies.libc] -version = "0.2.155" +libloading = "0.8.6" +lazy_static = "1.5.0" +libc = "0.2.167" [features] -default = ["plugin-api-v2"] +default = ["plugin-api-v4"] # Define external symbols with weak definition unix-weak-link = [] # Use the V1 plugin API, which is defined for versions below 9.0.0 plugin-api-v1 = ["qemu-plugin-sys/plugin-api-v1"] # Use the V2 plugin API, which is defined for version 9.0.0 plugin-api-v2 = ["qemu-plugin-sys/plugin-api-v2"] -# Use the V2 plugin API, which is defined for versions above 9.0.0 +# Use the V3 plugin API, which is defined for version 9.1.0 plugin-api-v3 = ["qemu-plugin-sys/plugin-api-v3"] +# Use the V4 plugin API, which is defined for versions above 9.1.0 +plugin-api-v4 = ["qemu-plugin-sys/plugin-api-v4"] num-traits = ["dep:num-traits"] diff --git a/qemu-plugin/README.md b/qemu-plugin/README.md index 4aef260..2112a15 100644 --- a/qemu-plugin/README.md +++ b/qemu-plugin/README.md @@ -65,7 +65,7 @@ edition = "2021" crate-type = ["cdylib"] [dependencies] -qemu-plugin = "9.0.0-v0" +qemu-plugin = "9.1.2-v0" anyhow = "1.0.75" ffi = "0.1.0" ctor = "0.2.6" @@ -80,9 +80,9 @@ library can only be compatible with one version at a time. To choose a version, listing like: ```toml -qemu-plugin = { version = "9.0.0-v0", features = ["plugin-api-v2"], default-features = false } +qemu-plugin = { version = "9.1.2-v0", features = ["plugin-api-v2"], default-features = false } ``` The `qemu-plugin` crate's default plugin version is set to the latest version that is -officially released in QEMU. Currently, this is V2, released in 8.2.4 and 9.0.0. If you -need a different version, you *must* set `default-features = false`. \ No newline at end of file +officially released in QEMU. Currently, this is V4, released in 9.2.0. If you need a +different version, you *must* set `default-features = false`. \ No newline at end of file diff --git a/qemu-plugin/src/error/mod.rs b/qemu-plugin/src/error/mod.rs index 26f16b5..ba5c796 100644 --- a/qemu-plugin/src/error/mod.rs +++ b/qemu-plugin/src/error/mod.rs @@ -57,6 +57,14 @@ pub enum Error { /// The register name name: String, }, + #[error("Error while reading {len} bytes from virtual address {addr:#x}")] + /// Error when reading memory from a virtual address fails + VaddrReadError { + /// The address read from + addr: u64, + /// The number of bytes read + len: usize, + }, #[error(transparent)] /// A transparently wrapped `std::str::Utf8Error` Utf8Error(#[from] std::str::Utf8Error), diff --git a/qemu-plugin/src/lib.rs b/qemu-plugin/src/lib.rs index 59bd49f..fa5f12e 100644 --- a/qemu-plugin/src/lib.rs +++ b/qemu-plugin/src/lib.rs @@ -64,7 +64,7 @@ //! crate-type = ["cdylib"] //! //! [dependencies] -//! qemu-plugin = "9.0.0-v0" +//! qemu-plugin = "9.1.2-v0" //! anyhow = "1.0.75" //! ffi = "0.1.0" //! ctor = "0.2.6" @@ -83,7 +83,7 @@ mod win_link_hook; use crate::error::{Error, Result}; #[cfg(feature = "num-traits")] use num_traits::{FromBytes, PrimInt}; -#[cfg(feature = "plugin-api-v3")] +#[cfg(not(any(feature = "plugin-api-v1", feature = "plugin-api-v2")))] use qemu_plugin_sys::qemu_plugin_cond; use qemu_plugin_sys::{ qemu_plugin_cb_flags, qemu_plugin_hwaddr, qemu_plugin_id_t, qemu_plugin_insn, @@ -91,7 +91,7 @@ use qemu_plugin_sys::{ qemu_plugin_tb, qemu_plugin_vcpu_simple_cb_t, qemu_plugin_vcpu_syscall_cb_t, qemu_plugin_vcpu_syscall_ret_cb_t, qemu_plugin_vcpu_tb_trans_cb_t, }; -#[cfg(any(feature = "plugin-api-v2", feature = "plugin-api-v3"))] +#[cfg(not(feature = "plugin-api-v1"))] use qemu_plugin_sys::{ qemu_plugin_read_register, qemu_plugin_reg_descriptor, qemu_plugin_register, qemu_plugin_scoreboard, qemu_plugin_u64, GArray, GByteArray, @@ -102,7 +102,7 @@ use std::{ path::PathBuf, sync::{Mutex, OnceLock}, }; -#[cfg(any(feature = "plugin-api-v2", feature = "plugin-api-v3"))] +#[cfg(not(feature = "plugin-api-v1"))] use std::{ fmt::{Debug, Formatter}, mem::MaybeUninit, @@ -120,10 +120,7 @@ extern "C" { fn g_free(mem: *mut c_void); } -#[cfg(all( - not(windows), - any(feature = "plugin-api-v2", feature = "plugin-api-v3") -))] +#[cfg(all(not(windows), not(feature = "plugin-api-v1")))] extern "C" { /// glib g_byte_array_new is provided by the QEMU program we are being linked into fn g_byte_array_new() -> *mut GByteArray; @@ -146,7 +143,7 @@ lazy_static::lazy_static! { }; } -#[cfg(all(windows, any(feature = "plugin-api-v2", feature = "plugin-api-v3")))] +#[cfg(all(windows, not(feature = "plugin-api-v1")))] lazy_static::lazy_static! { static ref G_BYTE_ARRAY_NEW: libloading::os::windows::Symbol *mut GByteArray> = { let lib = @@ -159,7 +156,7 @@ lazy_static::lazy_static! { }; } -#[cfg(all(windows, any(feature = "plugin-api-v2", feature = "plugin-api-v3")))] +#[cfg(all(windows, not(feature = "plugin-api-v1")))] lazy_static::lazy_static! { static ref G_BYTE_ARRAY_FREE: libloading::os::windows::Symbol *mut u8> = { let lib = @@ -172,7 +169,7 @@ lazy_static::lazy_static! { }; } -#[cfg(all(windows, any(feature = "plugin-api-v2", feature = "plugin-api-v3")))] +#[cfg(all(windows, not(feature = "plugin-api-v1")))] lazy_static::lazy_static! { static ref G_ARRAY_FREE: libloading::os::windows::Symbol *mut u8> = { let lib = @@ -198,7 +195,7 @@ unsafe fn g_free(mem: *mut c_void) { unsafe { G_FREE(mem) } } -#[cfg(all(windows, any(feature = "plugin-api-v2", feature = "plugin-api-v3")))] +#[cfg(all(windows, not(feature = "plugin-api-v1")))] /// Define g_byte_array_new, because on Windows we cannot delay link it /// /// # Safety @@ -210,7 +207,7 @@ unsafe fn g_byte_array_new() -> *mut GByteArray { unsafe { G_BYTE_ARRAY_NEW() } } -#[cfg(all(windows, any(feature = "plugin-api-v2", feature = "plugin-api-v3")))] +#[cfg(all(windows, not(feature = "plugin-api-v1")))] /// Define g_byte_array_free, because on Windows we cannot delay link it /// /// # Safety @@ -223,7 +220,7 @@ unsafe fn g_byte_array_free(array: *mut GByteArray, free_segment: bool) -> *mut unsafe { G_BYTE_ARRAY_FREE(array as *mut c_void, free_segment) } } -#[cfg(all(windows, any(feature = "plugin-api-v2", feature = "plugin-api-v3")))] +#[cfg(all(windows, not(feature = "plugin-api-v1")))] /// Define g_array_free, because on Windows we cannot delay link it /// /// # Safety @@ -237,7 +234,7 @@ unsafe fn g_array_free(array: *mut GArray, free_segment: bool) -> *mut u8 { /// The index of a vCPU pub type VCPUIndex = c_uint; -#[cfg(any(feature = "plugin-api-v2", feature = "plugin-api-v3"))] +#[cfg(not(feature = "plugin-api-v1"))] /// u64 member of an entry in a scoreboard, allows access to a specific u64 member in /// one given entry, located at a specified offset. Inline operations expect this as an /// entry. @@ -246,7 +243,7 @@ pub type PluginU64 = qemu_plugin_u64; pub type CallbackFlags = qemu_plugin_cb_flags; /// Memory read/write flags pub type MemRW = qemu_plugin_mem_rw; -#[cfg(any(feature = "plugin-api-v3"))] +#[cfg(not(any(feature = "plugin-api-v1", feature = "plugin-api-v2")))] /// A condition for a callback to be run pub type PluginCondition = qemu_plugin_cond; /// Plugin operations for inline operations @@ -416,7 +413,7 @@ impl<'a> TranslationBlock<'a> { }; } - #[cfg(feature = "plugin-api-v3")] + #[cfg(not(any(feature = "plugin-api-v1", feature = "plugin-api-v2")))] /// Register a callback to be conditionally run on execution of this translation /// block pub fn register_conditional_execute_callback( @@ -437,7 +434,7 @@ impl<'a> TranslationBlock<'a> { ) } - #[cfg(feature = "plugin-api-v3")] + #[cfg(not(any(feature = "plugin-api-v1", feature = "plugin-api-v2")))] /// Register a callback to be conditionally run on execution of this translation /// block pub fn register_conditional_execute_callback_flags( @@ -535,7 +532,7 @@ impl<'a> Instruction<'a> { data } - #[cfg(feature = "plugin-api-v3")] + #[cfg(not(any(feature = "plugin-api-v1", feature = "plugin-api-v2")))] /// Returns the data for this instruction. This method may only be called inside the /// callback in which the instruction is obtained, but the resulting data is owned. pub fn data(&self) -> Vec { @@ -632,7 +629,7 @@ impl<'a> Instruction<'a> { } /// Register a callback to be conditionally run on execution of this instruction - #[cfg(feature = "plugin-api-v3")] + #[cfg(not(any(feature = "plugin-api-v1", feature = "plugin-api-v2")))] pub fn register_conditional_execute_callback( &self, cb: F, @@ -652,7 +649,7 @@ impl<'a> Instruction<'a> { } /// Register a callback to be conditionally run on execution of this instruction - #[cfg(feature = "plugin-api-v3")] + #[cfg(not(any(feature = "plugin-api-v1", feature = "plugin-api-v2")))] pub fn register_conditional_execute_callback_flags( &self, cb: F, @@ -773,7 +770,7 @@ impl<'a> MemoryInfo<'a> { } } -#[cfg(any(feature = "plugin-api-v2", feature = "plugin-api-v3"))] +#[cfg(not(feature = "plugin-api-v1"))] #[derive(Clone)] /// Wrapper structure for a `qemu_plugin_register_descriptor` /// @@ -792,7 +789,7 @@ pub struct RegisterDescriptor<'a> { marker: PhantomData<&'a ()>, } -#[cfg(any(feature = "plugin-api-v2", feature = "plugin-api-v3"))] +#[cfg(not(feature = "plugin-api-v1"))] impl<'a> From for RegisterDescriptor<'a> { fn from(descriptor: qemu_plugin_reg_descriptor) -> Self { let name = unsafe { CStr::from_ptr(descriptor.name) } @@ -820,7 +817,7 @@ impl<'a> From for RegisterDescriptor<'a> { } } -#[cfg(any(feature = "plugin-api-v2", feature = "plugin-api-v3"))] +#[cfg(not(feature = "plugin-api-v1"))] impl<'a> Debug for RegisterDescriptor<'a> { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.debug_struct("RegisterDescriptor") @@ -830,7 +827,7 @@ impl<'a> Debug for RegisterDescriptor<'a> { } } -#[cfg(any(feature = "plugin-api-v2", feature = "plugin-api-v3"))] +#[cfg(not(feature = "plugin-api-v1"))] impl<'a> RegisterDescriptor<'a> { /// Read a register value /// @@ -947,7 +944,7 @@ impl<'a> HwAddr<'a> { } } -#[cfg(any(feature = "plugin-api-v2", feature = "plugin-api-v3"))] +#[cfg(not(feature = "plugin-api-v1"))] /// A wrapper structure for a `qemu_plugin_scoreboard *`. This is a way of having one /// entry per VCPU, the count of which is managed automatically by QEMU. Keep in mind /// that additional entries *and* existing entries will be allocated and reallocated by @@ -961,7 +958,7 @@ where marker: PhantomData<&'a T>, } -#[cfg(any(feature = "plugin-api-v2", feature = "plugin-api-v3"))] +#[cfg(not(feature = "plugin-api-v1"))] impl<'a, T> Scoreboard<'a, T> { /// Allocate a new scoreboard object. This must be freed by calling /// `qemu_plugin_scoreboard_free` (or by being dropped). @@ -987,14 +984,14 @@ impl<'a, T> Scoreboard<'a, T> { } } -#[cfg(any(feature = "plugin-api-v2", feature = "plugin-api-v3"))] +#[cfg(not(feature = "plugin-api-v1"))] impl<'a, T> Default for Scoreboard<'a, T> { fn default() -> Self { Self::new() } } -#[cfg(any(feature = "plugin-api-v2", feature = "plugin-api-v3"))] +#[cfg(not(feature = "plugin-api-v1"))] impl<'a, T> Drop for Scoreboard<'a, T> { fn drop(&mut self) { unsafe { @@ -1203,7 +1200,7 @@ where tb.register_execute_callback_flags(cb, flags); } -#[cfg(feature = "plugin-api-v3")] +#[cfg(not(any(feature = "plugin-api-v1", feature = "plugin-api-v2")))] /// Register a callback to be conditionally called when a translation block is executed. /// /// # Arguments @@ -1257,7 +1254,7 @@ pub fn qemu_plugin_register_vcpu_tb_exec_inline( } } -#[cfg(any(feature = "plugin-api-v2", feature = "plugin-api-v3"))] +#[cfg(not(feature = "plugin-api-v1"))] #[allow(clippy::not_unsafe_ptr_arg_deref)] /// Register an inline callback to be called when a translation block is executed. /// @@ -1309,7 +1306,7 @@ where insn.register_execute_callback_flags(cb, flags); } -#[cfg(feature = "plugin-api-v3")] +#[cfg(not(any(feature = "plugin-api-v1", feature = "plugin-api-v2")))] #[allow(clippy::not_unsafe_ptr_arg_deref)] /// Register a callback to be conditionally called when an instruction is executed. /// @@ -1359,7 +1356,7 @@ pub fn qemu_plugin_register_vcpu_insn_exec_inline( } } -#[cfg(any(feature = "plugin-api-v2", feature = "plugin-api-v3"))] +#[cfg(not(feature = "plugin-api-v1"))] #[allow(clippy::not_unsafe_ptr_arg_deref)] /// Register an inline callback to be called when an instruction is executed. /// @@ -1448,7 +1445,7 @@ pub fn qemu_plugin_register_vcpu_mem_inline( } } -#[cfg(any(feature = "plugin-api-v2", feature = "plugin-api-v3"))] +#[cfg(not(feature = "plugin-api-v1"))] #[allow(clippy::not_unsafe_ptr_arg_deref)] /// Register an inline callback for every memory transaction of a particular instruction. /// @@ -1651,7 +1648,7 @@ pub fn qemu_plugin_n_vcpus() -> Option { } } -#[cfg(any(feature = "plugin-api-v2", feature = "plugin-api-v3"))] +#[cfg(not(feature = "plugin-api-v1"))] /// Return the number of vCPUs, if running in system mode pub fn qemu_plugin_num_vcpus() -> Option { let vcpus = unsafe { crate::sys::qemu_plugin_num_vcpus() }; @@ -1675,7 +1672,7 @@ pub fn qemu_plugin_n_max_vcpus() -> Option { } } -#[cfg(any(feature = "plugin-api-v2", feature = "plugin-api-v3"))] +#[cfg(not(feature = "plugin-api-v1"))] /// Returns a potentially empty list of registers. This should be used from a /// qemu_plugin_register_vcpu_init_cb callback after the vcpu has been initialized. pub fn qemu_plugin_get_registers<'a>() -> Result>> { @@ -1703,26 +1700,48 @@ pub fn qemu_plugin_get_registers<'a>() -> Result>> { Ok(registers) } -#[cfg(any(feature = "plugin-api-v2", feature = "plugin-api-v3"))] +#[cfg(not(any( + feature = "plugin-api-v1", + feature = "plugin-api-v2", + feature = "plugin-api-v3" +)))] +/// Returns the contents of virtual memory +/// +/// # Arguments +/// +/// - `addr`: The virtual address to read from +/// - `len`: The number of bytes to read +pub fn qemu_plugin_read_memory_vaddr(addr: u64, len: usize) -> Result> { + use std::slice::from_raw_parts; + + let data = unsafe { g_byte_array_new() }; + if !unsafe { crate::sys::qemu_plugin_read_memory_vaddr(addr, data, len) } { + Err(Error::VaddrReadError { addr, len }) + } else { + Ok(unsafe { from_raw_parts((*data).data, (*data).len as usize) }.to_vec()) + } +} + +#[cfg(not(feature = "plugin-api-v1"))] /// Add a value to a `PluginU64` for a given VCPU pub fn qemu_plugin_u64_add(entry: PluginU64, vcpu_index: VCPUIndex, added: u64) -> Result<()> { unsafe { crate::sys::qemu_plugin_u64_add(entry, vcpu_index, added) }; Ok(()) } -#[cfg(any(feature = "plugin-api-v2", feature = "plugin-api-v3"))] +#[cfg(not(feature = "plugin-api-v1"))] /// Get the value of a `PluginU64` for a given VCPU pub fn qemu_plugin_u64_get(entry: PluginU64, vcpu_index: VCPUIndex) -> u64 { unsafe { crate::sys::qemu_plugin_u64_get(entry, vcpu_index) } } -#[cfg(any(feature = "plugin-api-v2", feature = "plugin-api-v3"))] +#[cfg(not(feature = "plugin-api-v1"))] /// Set the value of a `PluginU64` for a given VCPU pub fn qemu_plugin_u64_set(entry: PluginU64, vcpu_index: VCPUIndex, value: u64) { unsafe { crate::sys::qemu_plugin_u64_set(entry, vcpu_index, value) } } -#[cfg(any(feature = "plugin-api-v2", feature = "plugin-api-v3"))] +#[cfg(not(feature = "plugin-api-v1"))] /// Get the sum of all VCPU entries in a scoreboard pub fn qemu_plugin_scoreboard_sum(entry: PluginU64) -> u64 { unsafe { crate::sys::qemu_plugin_u64_sum(entry) } diff --git a/qemu-plugin/src/unix_weak_link/mod.rs b/qemu-plugin/src/unix_weak_link/mod.rs index b206997..74879d7 100644 --- a/qemu-plugin/src/unix_weak_link/mod.rs +++ b/qemu-plugin/src/unix_weak_link/mod.rs @@ -73,7 +73,7 @@ pub extern "C" fn qemu_plugin_register_vcpu_tb_exec_inline( ) { } -#[cfg(feature = "plugin-api-v2")] +#[cfg(not(feature = "plugin-api-v1"))] #[no_mangle] #[linkage = "weak"] pub extern "C" fn qemu_plugin_register_vcpu_tb_exec_inline_per_vcpu( @@ -105,7 +105,7 @@ pub extern "C" fn qemu_plugin_register_vcpu_insn_exec_inline( ) { } -#[cfg(feature = "plugin-api-v2")] +#[cfg(not(feature = "plugin-api-v1"))] #[no_mangle] #[linkage = "weak"] pub extern "C" fn qemu_plugin_register_vcpu_insn_exec_inline_per_vcpu( @@ -241,7 +241,7 @@ pub extern "C" fn qemu_plugin_register_vcpu_mem_inline( ) { } -#[cfg(feature = "plugin-api-v2")] +#[cfg(not(feature = "plugin-api-v1"))] #[no_mangle] #[linkage = "weak"] pub extern "C" fn qemu_plugin_register_vcpu_mem_inline_per_vcpu( @@ -309,7 +309,7 @@ pub extern "C" fn qemu_plugin_n_vcpus() -> ::std::os::raw::c_int { 0 } -#[cfg(feature = "plugin-api-v2")] +#[cfg(not(feature = "plugin-api-v1"))] #[no_mangle] #[linkage = "weak"] pub extern "C" fn qemu_plugin_num_vcpus() -> ::std::os::raw::c_int { @@ -361,14 +361,25 @@ pub extern "C" fn qemu_plugin_entry_code() -> u64 { 0 } -#[cfg(any(feature = "plugin-api-v2", feature = "plugin-api-v3"))] +#[cfg(not(feature = "plugin-api-v1"))] #[no_mangle] #[linkage = "weak"] pub extern "C" fn qemu_plugin_get_registers() -> *mut GArray { null_mut() } -#[cfg(any(feature = "plugin-api-v2", feature = "plugin-api-v3"))] +#[cfg(not(any( + feature = "plugin-api-v1", + feature = "plugin-api-v2", + feature = "plugin-api-v3" +)))] +#[no_mangle] +#[linkage = "weak"] +pub extern "C" fn qemu_plugin_read_memory_vaddr(_: u64, _: *mut GByteArray, _: usize) -> bool { + false +} + +#[cfg(not(feature = "plugin-api-v1"))] #[no_mangle] #[linkage = "weak"] pub extern "C" fn qemu_plugin_read_register( @@ -378,19 +389,19 @@ pub extern "C" fn qemu_plugin_read_register( 0 } -#[cfg(any(feature = "plugin-api-v2", feature = "plugin-api-v3"))] +#[cfg(not(feature = "plugin-api-v1"))] #[no_mangle] #[linkage = "weak"] pub extern "C" fn qemu_plugin_scoreboard_new(_: usize) -> *mut qemu_plugin_scoreboard { null_mut() } -#[cfg(any(feature = "plugin-api-v2", feature = "plugin-api-v3"))] +#[cfg(not(feature = "plugin-api-v1"))] #[no_mangle] #[linkage = "weak"] pub extern "C" fn qemu_plugin_scoreboard_free(_: *mut qemu_plugin_scoreboard) {} -#[cfg(any(feature = "plugin-api-v2", feature = "plugin-api-v3"))] +#[cfg(not(feature = "plugin-api-v1"))] #[no_mangle] #[linkage = "weak"] pub extern "C" fn qemu_plugin_scoreboard_find( @@ -400,24 +411,24 @@ pub extern "C" fn qemu_plugin_scoreboard_find( null_mut() } -#[cfg(any(feature = "plugin-api-v2", feature = "plugin-api-v3"))] +#[cfg(not(feature = "plugin-api-v1"))] #[no_mangle] #[linkage = "weak"] pub extern "C" fn qemu_plugin_u64_add(_: qemu_plugin_u64, _: ::std::os::raw::c_uint, _: u64) {} -#[cfg(any(feature = "plugin-api-v2", feature = "plugin-api-v3"))] +#[cfg(not(feature = "plugin-api-v1"))] #[no_mangle] #[linkage = "weak"] pub extern "C" fn qemu_plugin_u64_get(_: qemu_plugin_u64, _: ::std::os::raw::c_uint) -> u64 { 0 } -#[cfg(any(feature = "plugin-api-v2", feature = "plugin-api-v3"))] +#[cfg(not(feature = "plugin-api-v1"))] #[no_mangle] #[linkage = "weak"] pub extern "C" fn qemu_plugin_u64_set(_: qemu_plugin_u64, _: ::std::os::raw::c_uint, _: u64) {} -#[cfg(any(feature = "plugin-api-v2", feature = "plugin-api-v3"))] +#[cfg(not(feature = "plugin-api-v1"))] #[no_mangle] #[linkage = "weak"] pub extern "C" fn qemu_plugin_u64_sum(_: qemu_plugin_u64) {} diff --git a/qemu-plugin/src/version/mod.rs b/qemu-plugin/src/version/mod.rs index a967360..f218d10 100644 --- a/qemu-plugin/src/version/mod.rs +++ b/qemu-plugin/src/version/mod.rs @@ -4,4 +4,5 @@ /// A mapping of the QEMU plugin version (given in sys::QEMU_PLUGIN_VERSION) to the last /// QEMU version which supports that plugin version ( or "latest" if it is supported by /// the latest version of QEMU) -pub const COMPABILITY_MAP: [(u8, &str); 3] = [(1, "8.2.3"), (2, "9.0.0"), (3, "latest")]; +pub const COMPATIBILITY_MAP: [(u8, &str); 4] = + [(1, "8.2.3"), (2, "9.0.0"), (3, "9.1.0"), (4, "latest")]; diff --git a/qemu-plugin/src/win_link_hook/mod.rs b/qemu-plugin/src/win_link_hook/mod.rs index aaf68c6..1552099 100644 --- a/qemu-plugin/src/win_link_hook/mod.rs +++ b/qemu-plugin/src/win_link_hook/mod.rs @@ -56,7 +56,7 @@ extern "C" fn delaylink_hook(dli_notify: DliNotify, pdli: DELAYLOAD_INFO) -> HMO return HMODULE( libloading::os::windows::Library::this() .expect("Get QEMU module") - .into_raw(), + .into_raw() as *mut _, ); } } diff --git a/qemu/Cargo.toml b/qemu/Cargo.toml deleted file mode 100644 index 502d4d9..0000000 --- a/qemu/Cargo.toml +++ /dev/null @@ -1,886 +0,0 @@ -[package] -name = "qemu" -authors.workspace = true -categories.workspace = true -description = "QEMU binary installer" -edition.workspace = true -homepage.workspace = true -license.workspace = true -publish.workspace = true -readme.workspace = true -repository.workspace = true -version.workspace = true - -[[bin]] -name = "qemu-aarch64" -required-features = ["binaries", "aarch64-linux-user"] - -[[bin]] -name = "qemu-aarch64_be" -required-features = ["binaries", "aarch64_be-linux-user"] - -[[bin]] -name = "qemu-alpha" -required-features = ["binaries", "alpha-linux-user"] - -[[bin]] -name = "qemu-arm" -required-features = ["binaries", "arm-linux-user"] - -[[bin]] -name = "qemu-armeb" -required-features = ["binaries", "armeb-linux-user"] - -[[bin]] -name = "qemu-cris" -required-features = ["binaries", "cris-linux-user"] - -[[bin]] -name = "qemu-hexagon" -required-features = ["binaries", "hexagon-linux-user"] - -[[bin]] -name = "qemu-hppa" -required-features = ["binaries", "hppa-linux-user"] - -[[bin]] -name = "qemu-i386" -required-features = ["binaries", "i386-linux-user"] - -[[bin]] -name = "qemu-loongarch64" -required-features = ["binaries", "loongarch64-linux-user"] - -[[bin]] -name = "qemu-m68k" -required-features = ["binaries", "m68k-linux-user"] - -[[bin]] -name = "qemu-microblaze" -required-features = ["binaries", "microblaze-linux-user"] - -[[bin]] -name = "qemu-microblazeel" -required-features = ["binaries", "microblazeel-linux-user"] - -[[bin]] -name = "qemu-mips" -required-features = ["binaries", "mips-linux-user"] - -[[bin]] -name = "qemu-mips64" -required-features = ["binaries", "mips64-linux-user"] - -[[bin]] -name = "qemu-mips64el" -required-features = ["binaries", "mips64el-linux-user"] - -[[bin]] -name = "qemu-mipsel" -required-features = ["binaries", "mipsel-linux-user"] - -[[bin]] -name = "qemu-mipsn32" -required-features = ["binaries", "mipsn32-linux-user"] - -[[bin]] -name = "qemu-mipsn32el" -required-features = ["binaries", "mipsn32el-linux-user"] - -[[bin]] -name = "qemu-nios2" -required-features = ["binaries", "nios2-linux-user"] - -[[bin]] -name = "qemu-or1k" -required-features = ["binaries", "or1k-linux-user"] - -[[bin]] -name = "qemu-ppc" -required-features = ["binaries", "ppc-linux-user"] - -[[bin]] -name = "qemu-ppc64" -required-features = ["binaries", "ppc64-linux-user"] - -[[bin]] -name = "qemu-ppc64le" -required-features = ["binaries", "ppc64le-linux-user"] - -[[bin]] -name = "qemu-riscv32" -required-features = ["binaries", "riscv32-linux-user"] - -[[bin]] -name = "qemu-riscv64" -required-features = ["binaries", "riscv64-linux-user"] - -[[bin]] -name = "qemu-s390x" -required-features = ["binaries", "s390x-linux-user"] - -[[bin]] -name = "qemu-sh4" -required-features = ["binaries", "sh4-linux-user"] - -[[bin]] -name = "qemu-sh4eb" -required-features = ["binaries", "sh4eb-linux-user"] - -[[bin]] -name = "qemu-sparc" -required-features = ["binaries", "sparc-linux-user"] - -[[bin]] -name = "qemu-sparc32plus" -required-features = ["binaries", "sparc32plus-linux-user"] - -[[bin]] -name = "qemu-sparc64" -required-features = ["binaries", "sparc64-linux-user"] - -[[bin]] -name = "qemu-x86_64" -required-features = ["binaries", "x86_64-linux-user"] - -[[bin]] -name = "qemu-xtensa" -required-features = ["binaries", "xtensa-linux-user"] - -[[bin]] -name = "qemu-xtensaeb" -required-features = ["binaries", "xtensaeb-linux-user"] - -[[bin]] -name = "qemu-system-aarch64" -required-features = ["binaries", "aarch64-softmmu"] - -[[bin]] -name = "qemu-system-alpha" -required-features = ["binaries", "alpha-softmmu"] - -[[bin]] -name = "qemu-system-arm" -required-features = ["binaries", "arm-softmmu"] - -[[bin]] -name = "qemu-system-avr" -required-features = ["binaries", "avr-softmmu"] - -[[bin]] -name = "qemu-system-cris" -required-features = ["binaries", "cris-softmmu"] - -[[bin]] -name = "qemu-system-hppa" -required-features = ["binaries", "hppa-softmmu"] - -[[bin]] -name = "qemu-system-i386" -required-features = ["binaries", "i386-softmmu"] - -[[bin]] -name = "qemu-system-loongarch64" -required-features = ["binaries", "loongarch64-softmmu"] - -[[bin]] -name = "qemu-system-m68k" -required-features = ["binaries", "m68k-softmmu"] - -[[bin]] -name = "qemu-system-microblaze" -required-features = ["binaries", "microblaze-softmmu"] - -[[bin]] -name = "qemu-system-microblazeel" -required-features = ["binaries", "microblazeel-softmmu"] - -[[bin]] -name = "qemu-system-mips" -required-features = ["binaries", "mips-softmmu"] - -[[bin]] -name = "qemu-system-mips64" -required-features = ["binaries", "mips64-softmmu"] - -[[bin]] -name = "qemu-system-mips64el" -required-features = ["binaries", "mips64el-softmmu"] - -[[bin]] -name = "qemu-system-mipsel" -required-features = ["binaries", "mipsel-softmmu"] - -[[bin]] -name = "qemu-system-nios2" -required-features = ["binaries", "nios2-softmmu"] - -[[bin]] -name = "qemu-system-or1k" -required-features = ["binaries", "or1k-softmmu"] - -[[bin]] -name = "qemu-system-ppc" -required-features = ["binaries", "ppc-softmmu"] - -[[bin]] -name = "qemu-system-ppc64" -required-features = ["binaries", "ppc64-softmmu"] - -[[bin]] -name = "qemu-system-riscv32" -required-features = ["binaries", "riscv32-softmmu"] - -[[bin]] -name = "qemu-system-riscv64" -required-features = ["binaries", "riscv64-softmmu"] - -[[bin]] -name = "qemu-system-rx" -required-features = ["binaries", "rx-softmmu"] - -[[bin]] -name = "qemu-system-s390x" -required-features = ["binaries", "s390x-softmmu"] - -[[bin]] -name = "qemu-system-sh4" -required-features = ["binaries", "sh4-softmmu"] - -[[bin]] -name = "qemu-system-sh4eb" -required-features = ["binaries", "sh4eb-softmmu"] - -[[bin]] -name = "qemu-system-sparc" -required-features = ["binaries", "sparc-softmmu"] - -[[bin]] -name = "qemu-system-sparc64" -required-features = ["binaries", "sparc64-softmmu"] - -[[bin]] -name = "qemu-system-tricore" -required-features = ["binaries", "tricore-softmmu"] - -[[bin]] -name = "qemu-system-x86_64" -required-features = ["binaries", "x86_64-softmmu"] - -[[bin]] -name = "qemu-system-xtensa" -required-features = ["binaries", "xtensa-softmmu"] - -[[bin]] -name = "qemu-system-xtensaeb" -required-features = ["binaries", "xtensaeb-softmmu"] - -[target.'cfg(all(unix, target_os = "linux"))'.dependencies] -memfd-exec = { version = "0.2.1", optional = true } - -[build-dependencies] -anyhow = "1.0.86" -command-ext = "0.1.2" -num_cpus = "1.16.0" -reqwest = { version = "0.12.4", default-features = false, features = [ - "rustls-tls", - "blocking", -] } -tar = "0.4.40" -xz2 = "0.1.7" - -[features] -# Enable the aarch64-softmmu target -aarch64-softmmu = [] -# Enable the alpha-softmmu target -alpha-softmmu = [] -# Enable the arm-softmmu target -arm-softmmu = [] -# Enable the avr-softmmu target -avr-softmmu = [] -# Enable the cris-softmmu target -cris-softmmu = [] -# Enable the hppa-softmmu target -hppa-softmmu = [] -# Enable the i386-softmmu target -i386-softmmu = [] -# Enable the loongarch64-softmmu target -loongarch64-softmmu = [] -# Enable the m68k-softmmu target -m68k-softmmu = [] -# Enable the microblazeel-softmmu target -microblazeel-softmmu = [] -# Enable the microblaze-softmmu target -microblaze-softmmu = [] -# Enable the mips64el-softmmu target -mips64el-softmmu = [] -# Enable the mips64-softmmu target -mips64-softmmu = [] -# Enable the mipsel-softmmu target -mipsel-softmmu = [] -# Enable the mips-softmmu target -mips-softmmu = [] -# Enable the nios2-softmmu target -nios2-softmmu = [] -# Enable the or1k-softmmu target -or1k-softmmu = [] -# Enable the ppc64-softmmu target -ppc64-softmmu = [] -# Enable the ppc-softmmu target -ppc-softmmu = [] -# Enable the riscv32-softmmu target -riscv32-softmmu = [] -# Enable the riscv64-softmmu target -riscv64-softmmu = [] -# Enable the rx-softmmu target -rx-softmmu = [] -# Enable the s390x-softmmu target -s390x-softmmu = [] -# Enable the sh4eb-softmmu target -sh4eb-softmmu = [] -# Enable the sh4-softmmu target -sh4-softmmu = [] -# Enable the sparc64-softmmu target -sparc64-softmmu = [] -# Enable the sparc-softmmu target -sparc-softmmu = [] -# Enable the tricore-softmmu target -tricore-softmmu = [] -# Enable the x86_64-softmmu target -x86_64-softmmu = [] -# Enable the xtensaeb-softmmu target -xtensaeb-softmmu = [] -# Enable the xtensa-softmmu target -xtensa-softmmu = [] -# Enable the aarch64_be-linux-user target -aarch64_be-linux-user = [] -# Enable the aarch64-linux-user target -aarch64-linux-user = [] -# Enable the alpha-linux-user target -alpha-linux-user = [] -# Enable the armeb-linux-user target -armeb-linux-user = [] -# Enable the arm-linux-user target -arm-linux-user = [] -# Enable the cris-linux-user target -cris-linux-user = [] -# Enable the hexagon-linux-user target -hexagon-linux-user = [] -# Enable the hppa-linux-user target -hppa-linux-user = [] -# Enable the i386-linux-user target -i386-linux-user = [] -# Enable the loongarch64-linux-user target -loongarch64-linux-user = [] -# Enable the m68k-linux-user target -m68k-linux-user = [] -# Enable the microblazeel-linux-user target -microblazeel-linux-user = [] -# Enable the microblaze-linux-user target -microblaze-linux-user = [] -# Enable the mips64el-linux-user target -mips64el-linux-user = [] -# Enable the mips64-linux-user target -mips64-linux-user = [] -# Enable the mipsel-linux-user target -mipsel-linux-user = [] -# Enable the mips-linux-user target -mips-linux-user = [] -# Enable the mipsn32el-linux-user target -mipsn32el-linux-user = [] -# Enable the mipsn32-linux-user target -mipsn32-linux-user = [] -# Enable the nios2-linux-user target -nios2-linux-user = [] -# Enable the or1k-linux-user target -or1k-linux-user = [] -# Enable the ppc64le-linux-user target -ppc64le-linux-user = [] -# Enable the ppc64-linux-user target -ppc64-linux-user = [] -# Enable the ppc-linux-user target -ppc-linux-user = [] -# Enable the riscv32-linux-user target -riscv32-linux-user = [] -# Enable the riscv64-linux-user target -riscv64-linux-user = [] -# Enable the s390x-linux-user target -s390x-linux-user = [] -# Enable the sh4eb-linux-user target -sh4eb-linux-user = [] -# Enable the sh4-linux-user target -sh4-linux-user = [] -# Enable the sparc32plus-linux-user target -sparc32plus-linux-user = [] -# Enable the sparc64-linux-user target -sparc64-linux-user = [] -# Enable the sparc-linux-user target -sparc-linux-user = [] -# Enable the x86_64-linux-user target -x86_64-linux-user = [] -# Enable the xtensaeb-linux-user target -xtensaeb-linux-user = [] -# Enable the xtensa-linux-user target -xtensa-linux-user = [] - -softmmu = [ - "aarch64-softmmu", - "alpha-softmmu", - "arm-softmmu", - "avr-softmmu", - "cris-softmmu", - "hppa-softmmu", - "i386-softmmu", - "loongarch64-softmmu", - "m68k-softmmu", - "microblazeel-softmmu", - "microblaze-softmmu", - "mips64el-softmmu", - "mips64-softmmu", - "mipsel-softmmu", - "mips-softmmu", - "nios2-softmmu", - "or1k-softmmu", - "ppc64-softmmu", - "ppc-softmmu", - "riscv32-softmmu", - "riscv64-softmmu", - "rx-softmmu", - "s390x-softmmu", - "sh4eb-softmmu", - "sh4-softmmu", - "sparc64-softmmu", - "sparc-softmmu", - "tricore-softmmu", - "x86_64-softmmu", - "xtensaeb-softmmu", - "xtensa-softmmu", -] - -linux-user = [ - "aarch64_be-linux-user", - "aarch64-linux-user", - "alpha-linux-user", - "armeb-linux-user", - "arm-linux-user", - "cris-linux-user", - "hexagon-linux-user", - "hppa-linux-user", - "i386-linux-user", - "loongarch64-linux-user", - "m68k-linux-user", - "microblazeel-linux-user", - "microblaze-linux-user", - "mips64el-linux-user", - "mips64-linux-user", - "mipsel-linux-user", - "mips-linux-user", - "mipsn32el-linux-user", - "mipsn32-linux-user", - "nios2-linux-user", - "or1k-linux-user", - "ppc64le-linux-user", - "ppc64-linux-user", - "ppc-linux-user", - "riscv32-linux-user", - "riscv64-linux-user", - "s390x-linux-user", - "sh4eb-linux-user", - "sh4-linux-user", - "sparc32plus-linux-user", - "sparc64-linux-user", - "sparc-linux-user", - "x86_64-linux-user", - "xtensaeb-linux-user", - "xtensa-linux-user", -] - -default-targets = ["softmmu", "linux-user"] - - -# Enable the alsa audio driver -audio-drv-alsa = [] -# Enable the coreaudio audio driver -audio-drv-coreaudio = [] -# Enable the dsound audio driver -audio-drv-dsound = [] -# Enable the jack audio driver -audio-drv-jack = [] -# Enable the oss audio driver -audio-drv-oss = [] -# Enable the PulseAudio audio driver -audio-drv-pa = [] -# Enable the pipewire audio driver -audio-drv-pipewire = [] -# Enable the sdl audio driver -audio-drv-sdl = [] -# Enable the sndio audio driver -audio-drv-sndio = [] -# Enable the default audio driver -audio-drv-default = [] - -default-audio-drv = ["audio-drv-default"] - -# Enable static build -static = [] -# Enable common debug build options -debug = [] -# Enable compilation abort on warning -werror = [] -# Enable plugins via shared library loading -plugins = [] -# Enable the coroutine pool -coroutine-pool = [] -# Enable debug symbols and other information. Note that this may generate an -# archive file that is too big! -debug-info = [] -# Enable the hexagon idef parser -hexagon-idef-parser = [] -# Enable firmware blob installation -install-blobs = [] -# Enable QOM cast debugging support -qom-cast-debug = [] -# Enable Control Flow Integrity -cfi = [] -# Enable verbose CFI debug errors -cfi-debug = [] -# Graph lock debugging support -debug-graph-lock = [] -# Enable mutex debugging -debug-mutex = [] -# Enable coroutine stack usage debugging -debug-stack-usage = [] -# Enable fuzzing targets -fuzzing = [] -# Enable coverage tracking -gcov = [] -# Enable QEMU profiling with gprof -gprof = [] -# Enable link-time optimization -lto = [] -# Try to load modules from alternate paths for upgrades -module-upgrades = [] -# Enable dummy RNG -rng-none = [] -# Enable safe stack -safe-stack = [] -# Enable sanitizers -sanitizers = [] -# Enable stripping of binaries -strip = [] -# Enable TCG with bytecode interpreter (slow) -tcg-interpreter = [] -# Enable thread sanitizer -tsan = [] - -default-options = [ - "werror", - "coroutine-pool", - "hexagon-idef-parser", - "install-blobs", - "qom-cast-debug", -] - -# Enable dtrace backend -trace-backend-dtrace = [] -# Enable ftrace backend -trace-backend-ftrace = [] -# Enable log backend -trace-backend-log = [] -# Enable nop backend -trace-backend-nop = [] -# Enable simple backend -trace-backend-simple = [] -# Enable syslog backend -trace-backend-syslog = [] -# Enable ust backend -trace-backend-ust = [] - -default-trace-backend = ["trace-backend-log"] - - -# Enable auto coroutine backend -coroutine-backend-auto = [] -# Enable sigaltstack coroutine backend -coroutine-backend-sigaltstack = [] -# Enable ucontext coroutine backend -coroutine-backend-ucontext = [] -# Enable windows coroutine backend -coroutine-backend-windows = [] - -default-coroutine-backend = ["coroutine-backend-auto"] - -# Enable ALSA sound support -enable-feature-alsa = [] -# Enable attr/xattr support -enable-feature-attr = [] -# Enable PAM access control -enable-feature-auth-pam = [] -# Enable AVX2 optimizations -enable-feature-avx2 = [] -# Enable AVX512BW optimizations -enable-feature-avx512bw = [] -# Enable AVX512F optimizations -enable-feature-avx512f = [] -# Enable libblkio block device driver -enable-feature-blkio = [] -# Enable bochs image format support -enable-feature-bochs = [] -# Enable eBPF support -enable-feature-bpf = [] -# Enable brlapi character device driver -enable-feature-brlapi = [] -# Enable bzip2 support for DMG images -enable-feature-bzip2 = [] -# Enable CanoKey support -enable-feature-canokey = [] -# Enable cap_ng support -enable-feature-cap-ng = [] -# Enable Whether and how to find the capstone library -enable-feature-capstone = [] -# Enable cloop image format support -enable-feature-cloop = [] -# Enable Cocoa user interface (macOS only) -enable-feature-cocoa = [] -# Enable colo-proxy support -enable-feature-colo-proxy = [] -# Enable CoreAudio sound support -enable-feature-coreaudio = [] -# Enable Linux AF_ALG crypto backend driver -enable-feature-crypto-afalg = [] -# Enable CURL block device driver -enable-feature-curl = [] -# Enable curses UI -enable-feature-curses = [] -# Enable -display dbus support -enable-feature-dbus-display = [] -# Enable dmg image format support -enable-feature-dmg = [] -# Enable Documentations build support -enable-feature-docs = [] -# Enable DirectSound sound support -enable-feature-dsound = [] -# Enable FUSE block device export -enable-feature-fuse = [] -# Enable SEEK_HOLE/SEEK_DATA support for FUSE exports -enable-feature-fuse-lseek = [] -# Enable libgcrypt cryptography support -enable-feature-gcrypt = [] -# Enable Localization of the GTK+ user interface -enable-feature-gettext = [] -# Enable use libgio for D-Bus support -enable-feature-gio = [] -# Enable Glusterfs block device driver -enable-feature-glusterfs = [] -# Enable GNUTLS cryptography support -enable-feature-gnutls = [] -# Enable GTK+ user interface -enable-feature-gtk = [] -# Enable clipboard support for the gtk UI (EXPERIMENTAL, MAY HANG) -enable-feature-gtk-clipboard = [] -# Enable Build QEMU Guest Agent -enable-feature-guest-agent = [] -# Enable Build MSI package for the QEMU Guest Agent -enable-feature-guest-agent-msi = [] -# Enable HAX acceleration support -enable-feature-hax = [] -# Enable HVF acceleration support -enable-feature-hvf = [] -# Enable Font glyph conversion support -enable-feature-iconv = [] -# Enable JACK sound support -enable-feature-jack = [] -# Enable Linux keyring support -enable-feature-keyring = [] -# Enable KVM acceleration support -enable-feature-kvm = [] -# Enable l2tpv3 network backend support -enable-feature-l2tpv3 = [] -# Enable libdaxctl support -enable-feature-libdaxctl = [] -# Enable debuginfo support -enable-feature-libdw = [] -# Enable libiscsi userspace initiator -enable-feature-libiscsi = [] -# Enable Linux keyutils support -enable-feature-libkeyutils = [] -# Enable libnfs block device driver -enable-feature-libnfs = [] -# Enable libpmem support -enable-feature-libpmem = [] -# Enable ssh block device support -enable-feature-libssh = [] -# Enable Use libudev to enumerate host devices -enable-feature-libudev = [] -# Enable libusb support for USB passthrough -enable-feature-libusb = [] -# Enable build VDUSE Library -enable-feature-libvduse = [] -# Enable Linux AIO support -enable-feature-linux-aio = [] -# Enable Linux io_uring support -enable-feature-linux-io-uring = [] -# Enable block migration in the main migration stream -enable-feature-live-block-migration = [] -# Enable lzfse support for DMG images -enable-feature-lzfse = [] -# Enable lzo compression support -enable-feature-lzo = [] -# Enable enable libc malloc_trim() for memory optimization -enable-feature-malloc-trim = [] -# Enable membarrier system call (for Linux 4.14+ or Windows -enable-feature-membarrier = [] -# Enable modules support (non Windows) -enable-feature-modules = [] -# Enable Multipath persistent reservation passthrough -enable-feature-mpath = [] -# Enable Out of process device emulation support -enable-feature-multiprocess = [] -# Enable netmap network backend support -enable-feature-netmap = [] -# Enable nettle cryptography support -enable-feature-nettle = [] -# Enable libnuma support -enable-feature-numa = [] -# Enable NVMM acceleration support -enable-feature-nvmm = [] -# Enable OpenGL support -enable-feature-opengl = [] -# Enable OSS sound support -enable-feature-oss = [] -# Enable PulseAudio sound support -enable-feature-pa = [] -# Enable parallels image format support -enable-feature-parallels = [] -# Enable PipeWire sound support -enable-feature-pipewire = [] -# Enable PNG support with libpng -enable-feature-png = [] -# Enable Enable PVRDMA support -enable-feature-pvrdma = [] -# Enable qcow1 image format support -enable-feature-qcow1 = [] -# Enable qed image format support -enable-feature-qed = [] -# Enable build QGA VSS support (broken with MinGW) -enable-feature-qga-vss = [] -# Enable Ceph block device driver -enable-feature-rbd = [] -# Enable Enable RDMA-based migration -enable-feature-rdma = [] -# Enable replication support -enable-feature-replication = [] -# Enable SDL user interface -enable-feature-sdl = [] -# Enable SDL Image support for icons -enable-feature-sdl-image = [] -# Enable seccomp support -enable-feature-seccomp = [] -# Enable SELinux support in qemu-nbd -enable-feature-selinux = [] -# Enable libslirp user mode network backend support -enable-feature-slirp = [] -# Enable use smbd (at path --smbd=*) in slirp networking -enable-feature-slirp-smbd = [] -# Enable CA smartcard emulation support -enable-feature-smartcard = [] -# Enable snappy compression support -enable-feature-snappy = [] -# Enable sndio sound support -enable-feature-sndio = [] -# Enable sparse checker -enable-feature-sparse = [] -# Enable Spice server support -enable-feature-spice = [] -# Enable Spice protocol support -enable-feature-spice-protocol = [] -# Enable compiler-provided stack protection -enable-feature-stack-protector = [] -# Enable TCG support -enable-feature-tcg = [] -# Enable build support utilities that come with QEMU -enable-feature-tools = [] -# Enable TPM support -enable-feature-tpm = [] -# Enable U2F emulation support -enable-feature-u2f = [] -# Enable libusbredir support -enable-feature-usb-redir = [] -# Enable vde network backend support -enable-feature-vde = [] -# Enable vdi image format support -enable-feature-vdi = [] -# Enable VDUSE block export support -enable-feature-vduse-blk-export = [] -# Enable vfio-user server support -enable-feature-vfio-user-server = [] -# Enable vhdx image format support -enable-feature-vhdx = [] -# Enable vhost-user crypto backend support -enable-feature-vhost-crypto = [] -# Enable vhost kernel backend support -enable-feature-vhost-kernel = [] -# Enable vhost-net kernel acceleration support -enable-feature-vhost-net = [] -# Enable vhost-user backend support -enable-feature-vhost-user = [] -# Enable build vhost-user-blk server -enable-feature-vhost-user-blk-server = [] -# Enable vhost-vdpa kernel backend support -enable-feature-vhost-vdpa = [] -# Enable virgl rendering support -enable-feature-virglrenderer = [] -# Enable virtio-9p support -enable-feature-virtfs = [] -# Enable virtio-9p proxy helper support -enable-feature-virtfs-proxy-helper = [] -# Enable vmdk image format support -enable-feature-vmdk = [] -# Enable vmnet.framework network backend support -enable-feature-vmnet = [] -# Enable VNC server -enable-feature-vnc = [] -# Enable JPEG lossy compression for VNC server -enable-feature-vnc-jpeg = [] -# Enable SASL authentication for VNC server -enable-feature-vnc-sasl = [] -# Enable vpc image format support -enable-feature-vpc = [] -# Enable vte support for the gtk UI -enable-feature-vte = [] -# Enable vvfat image format support -enable-feature-vvfat = [] -# Enable WHPX acceleration support -enable-feature-whpx = [] -# Enable Xen backend support -enable-feature-xen = [] -# Enable Xen PCI passthrough support -enable-feature-xen-pci-passthrough = [] -# Enable xkbcommon support -enable-feature-xkbcommon = [] -# Enable zstd compression support -enable-feature-zstd = [] -# Enable all system emulation targets -enable-feature-system = [] -# Enable supported user emulation targets -enable-feature-user = [] -# Enable all linux usermode emulation targets -enable-feature-linux-user = [] -# Enable all BSD usermode emulation targets -enable-feature-bsd-user = [] -# Enable Position Independent Executables -enable-feature-pie = [] -# Enable TCG debugging (default is disabled) -enable-feature-debug-tcg = [] - -without-default-features = [] - -default = [ - "default-targets", - "default-audio-drv", - "default-options", - "default-trace-backend", - "default-coroutine-backend", -] - -binaries = ["dep:memfd-exec"] diff --git a/qemu/README.md b/qemu/README.md deleted file mode 100644 index 1d6177f..0000000 --- a/qemu/README.md +++ /dev/null @@ -1,139 +0,0 @@ -# qemu - -This crate provides an installer for QEMU binaries. You can use it to install QEMU -system and user mode emulators and use them in your code. - -## Table of Contents - -- [qemu](#qemu) - - [Table of Contents](#table-of-contents) - - [Dependencies](#dependencies) - - [Install Required Dependencies on Ubuntu](#install-required-dependencies-on-ubuntu) - - [Install Required Dependencies on Fedora](#install-required-dependencies-on-fedora) - - [Installation](#installation) - - [Usage](#usage) - - [Rust-executable wrapper for user emulator](#rust-executable-wrapper-for-user-emulator) - - [Cargo.toml](#cargotoml) - - [Feature Flags](#feature-flags) - - [Just install qemu-x86\_64 usermode emulator with default options](#just-install-qemu-x86_64-usermode-emulator-with-default-options) - - [Install an optimized qemu-x86\_64 usermode emulator](#install-an-optimized-qemu-x86_64-usermode-emulator) - - [Install qemu-system-arm emulator with customized options](#install-qemu-system-arm-emulator-with-customized-options) - - [Contributing](#contributing) - -## Dependencies - -To install this crate, you need all the dependencies required to build QEMU for your -system. There are some packages that are always required. The updated list can be found -[here](https://wiki.qemu.org/Hosts/Linux#Required_additional_packages). As of QEMU 7.3, -you can install the required packages with the distro-specific commands below. If you -encounter any other problems building, try checking the -[build instructions](https://github.com/qemu/qemu#building) for your platform. If you are -unable to fix your issue, please file an issue here! - -### Install Required Dependencies on Ubuntu - -```sh -$ sudo apt-get install git libglib2.0-dev libfdt-dev \ - libpixman-1-dev zlib1g-dev ninja-build -``` - -### Install Required Dependencies on Fedora - -```sh -$ sudo dnf install git glib2-devel libfdt-devel \ - pixman-devel zlib-devel bzip2 ninja-build python3 -``` - -## Installation - -To install QEMU binaries (see feature flags for direction on customizing the build): - -```sh -cargo install qemu --features=binaries,lto,plugins -``` - -## Usage - -See the feature flags section for information on enabling targets, but once you have -an installation, you can use the binary! - -### Rust-executable wrapper for user emulator - -There are crates available for binary distributions of each qemu program, and they all -essentially implement this pattern. This executable will run `qemu-aarch64` as a wrapper -and pass through command line args and stdio to the executable. Much more complicated -things are possible now that we have a binary available straight in Rust though, so -the sky is the limit! - -#### Cargo.toml - -```toml -[package] -name = "qemu-aarch64" -version = "0.1.0" -edition = "2021" -description = "QEMU binary installer for qemu-aarch64" -license = "MIT" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html -[dependencies] -memfd-exec = "2.1.0" -qemu = { version = "9.0.0", features = ["qemu-aarch64"] } -``` - -```rust -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_AARCH64_LINUX_USEr; - -use std::env::args; - -fn main() { - let qemu = QEMU_AARCH64_LINUX_USEr; - let mut args: Vec = args().collect(); - args.remove(0); - MemFdExecutable::new("qemu-aarch64", qemu) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start qemu process") - .wait() - .expect("Qemu process failed"); -} -``` - -## Feature Flags - -The feature flags of this crate provide an interface to the configure options for -QEMU. By default, all flags are set just as QEMU's `configure` script sets them with -the exception of targets (see [Important Note](#important-note)). Some examples of how -to configure this crate as a dependency: - -### Just install qemu-x86_64 usermode emulator with default options - -This will make the `qemu-x86_64` binary available. - -```toml -qemu = { version = "9.0.0", features = ["qemu-x86_64"] } -``` - -### Install an optimized qemu-x86_64 usermode emulator - -This will also make the `qemu-x86_64` binary available, but will strip and optimize it -with `lto`. - -```toml -qemu = { version = "9.0.0", features = ["qemu-x86_64", "lto", "strip"] -``` - -### Install qemu-system-arm emulator with customized options - -We can also selectively opt in to features. Use this only if you really need it! These -are all enabled by default if they are available anyway! See the [qemu -documentation](https://www.qemu.org/docs/master/devel/build-system.html#stage-1-configure) -about configure options for more details. - -## Contributing - -Contributions are welcome for any reason! diff --git a/qemu/build.rs b/qemu/build.rs deleted file mode 100644 index 419b859..0000000 --- a/qemu/build.rs +++ /dev/null @@ -1,926 +0,0 @@ -//! Build script for QEMU binaries. Configures QEMU by converting crate features to configure -//! arguments, then builds it into the crate OUT_DIR. - -use anyhow::{anyhow, Error, Result}; -use command_ext::CommandExtCheck; -use reqwest::blocking::get; -use std::{ - env::var, - fs::{create_dir_all, File, OpenOptions}, - path::{Path, PathBuf}, - process::Command, -}; -use tar::Archive; -use xz2::read::XzDecoder; - -const QEMU_SRC_URL_BASE: &str = "https://download.qemu.org/"; -const QEMU_VERSION: &str = "9.0.0"; - -pub struct ConfigureArgs(Vec); - -impl ConfigureArgs { - fn targets_from_features() -> String { - let mut targets = Vec::new(); - - if cfg!(feature = "aarch64-softmmu") { - targets.push("aarch64-softmmu".to_string()); - } - if cfg!(feature = "alpha-softmmu") { - targets.push("alpha-softmmu".to_string()); - } - if cfg!(feature = "arm-softmmu") { - targets.push("arm-softmmu".to_string()); - } - if cfg!(feature = "avr-softmmu") { - targets.push("avr-softmmu".to_string()); - } - if cfg!(feature = "cris-softmmu") { - targets.push("cris-softmmu".to_string()); - } - if cfg!(feature = "hppa-softmmu") { - targets.push("hppa-softmmu".to_string()); - } - if cfg!(feature = "i386-softmmu") { - targets.push("i386-softmmu".to_string()); - } - if cfg!(feature = "loongarch64-softmmu") { - targets.push("loongarch64-softmmu".to_string()); - } - if cfg!(feature = "m68k-softmmu") { - targets.push("m68k-softmmu".to_string()); - } - if cfg!(feature = "microblazeel-softmmu") { - targets.push("microblazeel-softmmu".to_string()); - } - if cfg!(feature = "microblaze-softmmu") { - targets.push("microblaze-softmmu".to_string()); - } - if cfg!(feature = "mips64el-softmmu") { - targets.push("mips64el-softmmu".to_string()); - } - if cfg!(feature = "mips64-softmmu") { - targets.push("mips64-softmmu".to_string()); - } - if cfg!(feature = "mipsel-softmmu") { - targets.push("mipsel-softmmu".to_string()); - } - if cfg!(feature = "mips-softmmu") { - targets.push("mips-softmmu".to_string()); - } - if cfg!(feature = "nios2-softmmu") { - targets.push("nios2-softmmu".to_string()); - } - if cfg!(feature = "or1k-softmmu") { - targets.push("or1k-softmmu".to_string()); - } - if cfg!(feature = "ppc64-softmmu") { - targets.push("ppc64-softmmu".to_string()); - } - if cfg!(feature = "ppc-softmmu") { - targets.push("ppc-softmmu".to_string()); - } - if cfg!(feature = "riscv32-softmmu") { - targets.push("riscv32-softmmu".to_string()); - } - if cfg!(feature = "riscv64-softmmu") { - targets.push("riscv64-softmmu".to_string()); - } - if cfg!(feature = "rx-softmmu") { - targets.push("rx-softmmu".to_string()); - } - if cfg!(feature = "s390x-softmmu") { - targets.push("s390x-softmmu".to_string()); - } - if cfg!(feature = "sh4eb-softmmu") { - targets.push("sh4eb-softmmu".to_string()); - } - if cfg!(feature = "sh4-softmmu") { - targets.push("sh4-softmmu".to_string()); - } - if cfg!(feature = "sparc64-softmmu") { - targets.push("sparc64-softmmu".to_string()); - } - if cfg!(feature = "sparc-softmmu") { - targets.push("sparc-softmmu".to_string()); - } - if cfg!(feature = "tricore-softmmu") { - targets.push("tricore-softmmu".to_string()); - } - if cfg!(feature = "x86_64-softmmu") { - targets.push("x86_64-softmmu".to_string()); - } - if cfg!(feature = "xtensaeb-softmmu") { - targets.push("xtensaeb-softmmu".to_string()); - } - if cfg!(feature = "xtensa-softmmu") { - targets.push("xtensa-softmmu".to_string()); - } - if cfg!(feature = "aarch64_be-linux-user") { - targets.push("aarch64_be-linux-user".to_string()); - } - if cfg!(feature = "aarch64-linux-user") { - targets.push("aarch64-linux-user".to_string()); - } - if cfg!(feature = "alpha-linux-user") { - targets.push("alpha-linux-user".to_string()); - } - if cfg!(feature = "armeb-linux-user") { - targets.push("armeb-linux-user".to_string()); - } - if cfg!(feature = "arm-linux-user") { - targets.push("arm-linux-user".to_string()); - } - if cfg!(feature = "cris-linux-user") { - targets.push("cris-linux-user".to_string()); - } - if cfg!(feature = "hexagon-linux-user") { - targets.push("hexagon-linux-user".to_string()); - } - if cfg!(feature = "hppa-linux-user") { - targets.push("hppa-linux-user".to_string()); - } - if cfg!(feature = "i386-linux-user") { - targets.push("i386-linux-user".to_string()); - } - if cfg!(feature = "loongarch64-linux-user") { - targets.push("loongarch64-linux-user".to_string()); - } - if cfg!(feature = "m68k-linux-user") { - targets.push("m68k-linux-user".to_string()); - } - if cfg!(feature = "microblazeel-linux-user") { - targets.push("microblazeel-linux-user".to_string()); - } - if cfg!(feature = "microblaze-linux-user") { - targets.push("microblaze-linux-user".to_string()); - } - if cfg!(feature = "mips64el-linux-user") { - targets.push("mips64el-linux-user".to_string()); - } - if cfg!(feature = "mips64-linux-user") { - targets.push("mips64-linux-user".to_string()); - } - if cfg!(feature = "mipsel-linux-user") { - targets.push("mipsel-linux-user".to_string()); - } - if cfg!(feature = "mips-linux-user") { - targets.push("mips-linux-user".to_string()); - } - if cfg!(feature = "mipsn32el-linux-user") { - targets.push("mipsn32el-linux-user".to_string()); - } - if cfg!(feature = "mipsn32-linux-user") { - targets.push("mipsn32-linux-user".to_string()); - } - if cfg!(feature = "nios2-linux-user") { - targets.push("nios2-linux-user".to_string()); - } - if cfg!(feature = "or1k-linux-user") { - targets.push("or1k-linux-user".to_string()); - } - if cfg!(feature = "ppc64le-linux-user") { - targets.push("ppc64le-linux-user".to_string()); - } - if cfg!(feature = "ppc64-linux-user") { - targets.push("ppc64-linux-user".to_string()); - } - if cfg!(feature = "ppc-linux-user") { - targets.push("ppc-linux-user".to_string()); - } - if cfg!(feature = "riscv32-linux-user") { - targets.push("riscv32-linux-user".to_string()); - } - if cfg!(feature = "riscv64-linux-user") { - targets.push("riscv64-linux-user".to_string()); - } - if cfg!(feature = "s390x-linux-user") { - targets.push("s390x-linux-user".to_string()); - } - if cfg!(feature = "sh4eb-linux-user") { - targets.push("sh4eb-linux-user".to_string()); - } - if cfg!(feature = "sh4-linux-user") { - targets.push("sh4-linux-user".to_string()); - } - if cfg!(feature = "sparc32plus-linux-user") { - targets.push("sparc32plus-linux-user".to_string()); - } - if cfg!(feature = "sparc64-linux-user") { - targets.push("sparc64-linux-user".to_string()); - } - if cfg!(feature = "sparc-linux-user") { - targets.push("sparc-linux-user".to_string()); - } - if cfg!(feature = "x86_64-linux-user") { - targets.push("x86_64-linux-user".to_string()); - } - if cfg!(feature = "xtensaeb-linux-user") { - targets.push("xtensaeb-linux-user".to_string()); - } - if cfg!(feature = "xtensa-linux-user") { - targets.push("xtensa-linux-user".to_string()); - } - - format!("--target-list={}", targets.join(",")) - } - - fn audio_drv_from_features() -> String { - let mut audio_drvs = Vec::new(); - - if cfg!(feature = "audio-drv-alsa") { - audio_drvs.push("alsa".to_string()); - } - if cfg!(feature = "audio-drv-coreaudio") { - audio_drvs.push("coreaudio".to_string()); - } - if cfg!(feature = "audio-drv-dsound") { - audio_drvs.push("dsound".to_string()); - } - if cfg!(feature = "audio-drv-jack") { - audio_drvs.push("jack".to_string()); - } - if cfg!(feature = "audio-drv-oss") { - audio_drvs.push("oss".to_string()); - } - if cfg!(feature = "audio-drv-pa") { - audio_drvs.push("pa".to_string()); - } - if cfg!(feature = "audio-drv-pipewire") { - audio_drvs.push("pipewire".to_string()); - } - if cfg!(feature = "audio-drv-sdl") { - audio_drvs.push("sdl".to_string()); - } - if cfg!(feature = "audio-drv-sndio") { - audio_drvs.push("sndio".to_string()); - } - if cfg!(feature = "audio-drv-default") { - audio_drvs.push("default".to_string()); - } - - format!("--audio-drv-list={}", audio_drvs.join(",")) - } - - fn options_from_features() -> Vec { - let mut options = Vec::new(); - - if cfg!(feature = "static") { - options.push("--static".to_string()); - } - if cfg!(feature = "debug") { - options.push("--enable-debug".to_string()); - } - if cfg!(feature = "werror") { - options.push("--enable-werror".to_string()); - } - if cfg!(feature = "plugins") { - options.push("--enable-plugins".to_string()); - } - if !cfg!(feature = "coroutine-pool") { - options.push("--disable-coroutine-pool".to_string()); - } - if !cfg!(feature = "debug-info") { - options.push("--disable-debug-info".to_string()); - } - if !cfg!(feature = "hexagon-idef-parser") { - options.push("--disable-hexagon-idef-parser".to_string()); - } - if !cfg!(feature = "install-blobs") { - options.push("--disable-install-blobs".to_string()); - } - if !cfg!(feature = "qom-cast-debug") { - options.push("--disable-qom-cast-debug".to_string()); - } - if cfg!(feature = "cfi") { - options.push("--enable-cfi".to_string()); - } - if cfg!(feature = "cfi-debug") { - options.push("--enable-cfi-debug".to_string()); - } - if cfg!(feature = "debug-graph-lock") { - options.push("--enable-debug-graph-lock".to_string()); - } - if cfg!(feature = "debug-mutex") { - options.push("--enable-debug-mutex".to_string()); - } - if cfg!(feature = "debug-stack-usage") { - options.push("--enable-debug-stack-usage".to_string()); - } - if cfg!(feature = "fuzzing") { - options.push("--enable-fuzzing".to_string()); - } - if cfg!(feature = "gcov") { - options.push("--enable-gcov".to_string()); - } - if cfg!(feature = "gprof") { - options.push("--enable-gprof".to_string()); - } - if cfg!(feature = "lto") { - options.push("--enable-lto".to_string()); - } - if cfg!(feature = "module-upgrades") { - options.push("--enable-module-upgrades".to_string()); - } - if cfg!(feature = "rng-none") { - options.push("--enable-rng-none".to_string()); - } - if cfg!(feature = "safe-stack") { - options.push("--enable-safe-stack".to_string()); - } - if cfg!(feature = "sanitizers") { - options.push("--enable-sanitizers".to_string()); - } - if cfg!(feature = "strip") { - options.push("--enable-strip".to_string()); - } - if cfg!(feature = "tcg-interpreter") { - options.push("--enable-tcg-interpreter".to_string()); - } - if cfg!(feature = "tsan") { - options.push("--enable-tsan".to_string()); - } - - options - } - - fn trace_backends_from_features() -> String { - let mut trace_backends = Vec::new(); - if cfg!(feature = "trace-backend-dtrace") { - trace_backends.push("dtrace".to_string()); - } - if cfg!(feature = "trace-backend-ftrace") { - trace_backends.push("ftrace".to_string()); - } - if cfg!(feature = "trace-backend-log") { - trace_backends.push("log".to_string()); - } - if cfg!(feature = "trace-backend-nop") { - trace_backends.push("nop".to_string()); - } - if cfg!(feature = "trace-backend-simple") { - trace_backends.push("simple".to_string()); - } - if cfg!(feature = "trace-backend-syslog") { - trace_backends.push("syslog".to_string()); - } - if cfg!(feature = "trace-backend-ust") { - trace_backends.push("ust".to_string()); - } - - format!("--enable-trace-backends={}", trace_backends.join(",")) - } - - fn coroutine_backend_from_features() -> String { - if cfg!(feature = "coroutine-backend-auto") { - "auto" - } else if cfg!(feature = "coroutine-backend-sigaltstack") { - "sigaltstack" - } else if cfg!(feature = "coroutine-backend-ucontext") { - "ucontext" - } else if cfg!(feature = "coroutine-backend-windows") { - "windows" - } else { - panic!("No coroutine backend selected"); - } - .to_string() - } - - pub fn features_from_features() -> Vec { - let mut features = Vec::new(); - if !cfg!(feature = "without-default-features") { - return features; - } - if cfg!(feature = "enable-feature-alsa") { - features.push("--enable-alsa".to_string()) - } - if cfg!(feature = "enable-feature-attr") { - features.push("--enable-attr".to_string()) - } - if cfg!(feature = "enable-feature-auth-pam") { - features.push("--enable-auth-pam".to_string()) - } - if cfg!(feature = "enable-feature-avx2") { - features.push("--enable-avx2".to_string()) - } - if cfg!(feature = "enable-feature-avx512bw") { - features.push("--enable-avx512bw".to_string()) - } - if cfg!(feature = "enable-feature-avx512f") { - features.push("--enable-avx512f".to_string()) - } - if cfg!(feature = "enable-feature-blkio") { - features.push("--enable-blkio".to_string()) - } - if cfg!(feature = "enable-feature-bochs") { - features.push("--enable-bochs".to_string()) - } - if cfg!(feature = "enable-feature-bpf") { - features.push("--enable-bpf".to_string()) - } - if cfg!(feature = "enable-feature-brlapi") { - features.push("--enable-brlapi".to_string()) - } - if cfg!(feature = "enable-feature-bzip2") { - features.push("--enable-bzip2".to_string()) - } - if cfg!(feature = "enable-feature-canokey") { - features.push("--enable-canokey".to_string()) - } - if cfg!(feature = "enable-feature-cap-ng") { - features.push("--enable-cap-ng".to_string()) - } - if cfg!(feature = "enable-feature-capstone") { - features.push("--enable-capstone".to_string()) - } - if cfg!(feature = "enable-feature-cloop") { - features.push("--enable-cloop".to_string()) - } - if cfg!(feature = "enable-feature-cocoa") { - features.push("--enable-cocoa".to_string()) - } - if cfg!(feature = "enable-feature-colo-proxy") { - features.push("--enable-colo-proxy".to_string()) - } - if cfg!(feature = "enable-feature-coreaudio") { - features.push("--enable-coreaudio".to_string()) - } - if cfg!(feature = "enable-feature-crypto-afalg") { - features.push("--enable-crypto-afalg".to_string()) - } - if cfg!(feature = "enable-feature-curl") { - features.push("--enable-curl".to_string()) - } - if cfg!(feature = "enable-feature-curses") { - features.push("--enable-curses".to_string()) - } - if cfg!(feature = "enable-feature-dbus-display") { - features.push("--enable-dbus-display".to_string()) - } - if cfg!(feature = "enable-feature-dmg") { - features.push("--enable-dmg".to_string()) - } - if cfg!(feature = "enable-feature-docs") { - features.push("--enable-docs".to_string()) - } - if cfg!(feature = "enable-feature-dsound") { - features.push("--enable-dsound".to_string()) - } - if cfg!(feature = "enable-feature-fuse") { - features.push("--enable-fuse".to_string()) - } - if cfg!(feature = "enable-feature-fuse-lseek") { - features.push("--enable-fuse-lseek".to_string()) - } - if cfg!(feature = "enable-feature-gcrypt") { - features.push("--enable-gcrypt".to_string()) - } - if cfg!(feature = "enable-feature-gettext") { - features.push("--enable-gettext".to_string()) - } - if cfg!(feature = "enable-feature-gio") { - features.push("--enable-gio".to_string()) - } - if cfg!(feature = "enable-feature-glusterfs") { - features.push("--enable-glusterfs".to_string()) - } - if cfg!(feature = "enable-feature-gnutls") { - features.push("--enable-gnutls".to_string()) - } - if cfg!(feature = "enable-feature-gtk") { - features.push("--enable-gtk".to_string()) - } - if cfg!(feature = "enable-feature-gtk-clipboard") { - features.push("--enable-gtk-clipboard".to_string()) - } - if cfg!(feature = "enable-feature-guest-agent") { - features.push("--enable-guest-agent".to_string()) - } - if cfg!(feature = "enable-feature-guest-agent-msi") { - features.push("--enable-guest-agent-msi".to_string()) - } - if cfg!(feature = "enable-feature-hax") { - features.push("--enable-hax".to_string()) - } - if cfg!(feature = "enable-feature-hvf") { - features.push("--enable-hvf".to_string()) - } - if cfg!(feature = "enable-feature-iconv") { - features.push("--enable-iconv".to_string()) - } - if cfg!(feature = "enable-feature-jack") { - features.push("--enable-jack".to_string()) - } - if cfg!(feature = "enable-feature-keyring") { - features.push("--enable-keyring".to_string()) - } - if cfg!(feature = "enable-feature-kvm") { - features.push("--enable-kvm".to_string()) - } - if cfg!(feature = "enable-feature-l2tpv3") { - features.push("--enable-l2tpv3".to_string()) - } - if cfg!(feature = "enable-feature-libdaxctl") { - features.push("--enable-libdaxctl".to_string()) - } - if cfg!(feature = "enable-feature-libdw") { - features.push("--enable-libdw".to_string()) - } - if cfg!(feature = "enable-feature-libiscsi") { - features.push("--enable-libiscsi".to_string()) - } - if cfg!(feature = "enable-feature-libkeyutils") { - features.push("--enable-libkeyutils".to_string()) - } - if cfg!(feature = "enable-feature-libnfs") { - features.push("--enable-libnfs".to_string()) - } - if cfg!(feature = "enable-feature-libpmem") { - features.push("--enable-libpmem".to_string()) - } - if cfg!(feature = "enable-feature-libssh") { - features.push("--enable-libssh".to_string()) - } - if cfg!(feature = "enable-feature-libudev") { - features.push("--enable-libudev".to_string()) - } - if cfg!(feature = "enable-feature-libusb") { - features.push("--enable-libusb".to_string()) - } - if cfg!(feature = "enable-feature-libvduse") { - features.push("--enable-libvduse".to_string()) - } - if cfg!(feature = "enable-feature-linux-aio") { - features.push("--enable-linux-aio".to_string()) - } - if cfg!(feature = "enable-feature-linux-io-uring") { - features.push("--enable-linux-io-uring".to_string()) - } - if cfg!(feature = "enable-feature-live-block-migration") { - features.push("--enable-live-block-migration".to_string()) - } - if cfg!(feature = "enable-feature-lzfse") { - features.push("--enable-lzfse".to_string()) - } - if cfg!(feature = "enable-feature-lzo") { - features.push("--enable-lzo".to_string()) - } - if cfg!(feature = "enable-feature-malloc-trim") { - features.push("--enable-malloc-trim".to_string()) - } - if cfg!(feature = "enable-feature-membarrier") { - features.push("--enable-membarrier".to_string()) - } - if cfg!(feature = "enable-feature-modules") { - features.push("--enable-modules".to_string()) - } - if cfg!(feature = "enable-feature-mpath") { - features.push("--enable-mpath".to_string()) - } - if cfg!(feature = "enable-feature-multiprocess") { - features.push("--enable-multiprocess".to_string()) - } - if cfg!(feature = "enable-feature-netmap") { - features.push("--enable-netmap".to_string()) - } - if cfg!(feature = "enable-feature-nettle") { - features.push("--enable-nettle".to_string()) - } - if cfg!(feature = "enable-feature-numa") { - features.push("--enable-numa".to_string()) - } - if cfg!(feature = "enable-feature-nvmm") { - features.push("--enable-nvmm".to_string()) - } - if cfg!(feature = "enable-feature-opengl") { - features.push("--enable-opengl".to_string()) - } - if cfg!(feature = "enable-feature-oss") { - features.push("--enable-oss".to_string()) - } - if cfg!(feature = "enable-feature-pa") { - features.push("--enable-pa".to_string()) - } - if cfg!(feature = "enable-feature-parallels") { - features.push("--enable-parallels".to_string()) - } - if cfg!(feature = "enable-feature-pipewire") { - features.push("--enable-pipewire".to_string()) - } - if cfg!(feature = "enable-feature-png") { - features.push("--enable-png".to_string()) - } - if cfg!(feature = "enable-feature-pvrdma") { - features.push("--enable-pvrdma".to_string()) - } - if cfg!(feature = "enable-feature-qcow1") { - features.push("--enable-qcow1".to_string()) - } - if cfg!(feature = "enable-feature-qed") { - features.push("--enable-qed".to_string()) - } - if cfg!(feature = "enable-feature-qga-vss") { - features.push("--enable-qga-vss".to_string()) - } - if cfg!(feature = "enable-feature-rbd") { - features.push("--enable-rbd".to_string()) - } - if cfg!(feature = "enable-feature-rdma") { - features.push("--enable-rdma".to_string()) - } - if cfg!(feature = "enable-feature-replication") { - features.push("--enable-replication".to_string()) - } - if cfg!(feature = "enable-feature-sdl") { - features.push("--enable-sdl".to_string()) - } - if cfg!(feature = "enable-feature-sdl-image") { - features.push("--enable-sdl-image".to_string()) - } - if cfg!(feature = "enable-feature-seccomp") { - features.push("--enable-seccomp".to_string()) - } - if cfg!(feature = "enable-feature-selinux") { - features.push("--enable-selinux".to_string()) - } - if cfg!(feature = "enable-feature-slirp") { - features.push("--enable-slirp".to_string()) - } - if cfg!(feature = "enable-feature-slirp-smbd") { - features.push("--enable-slirp-smbd".to_string()) - } - if cfg!(feature = "enable-feature-smartcard") { - features.push("--enable-smartcard".to_string()) - } - if cfg!(feature = "enable-feature-snappy") { - features.push("--enable-snappy".to_string()) - } - if cfg!(feature = "enable-feature-sndio") { - features.push("--enable-sndio".to_string()) - } - if cfg!(feature = "enable-feature-sparse") { - features.push("--enable-sparse".to_string()) - } - if cfg!(feature = "enable-feature-spice") { - features.push("--enable-spice".to_string()) - } - if cfg!(feature = "enable-feature-spice-protocol") { - features.push("--enable-spice-protocol".to_string()) - } - if cfg!(feature = "enable-feature-stack-protector") { - features.push("--enable-stack-protector".to_string()) - } - if cfg!(feature = "enable-feature-tcg") { - features.push("--enable-tcg".to_string()) - } - if cfg!(feature = "enable-feature-tools") { - features.push("--enable-tools".to_string()) - } - if cfg!(feature = "enable-feature-tpm") { - features.push("--enable-tpm".to_string()) - } - if cfg!(feature = "enable-feature-u2f") { - features.push("--enable-u2f".to_string()) - } - if cfg!(feature = "enable-feature-usb-redir") { - features.push("--enable-usb-redir".to_string()) - } - if cfg!(feature = "enable-feature-vde") { - features.push("--enable-vde".to_string()) - } - if cfg!(feature = "enable-feature-vdi") { - features.push("--enable-vdi".to_string()) - } - if cfg!(feature = "enable-feature-vduse-blk-export") { - features.push("--enable-vduse-blk-export".to_string()) - } - if cfg!(feature = "enable-feature-vfio-user-server") { - features.push("--enable-vfio-user-server".to_string()) - } - if cfg!(feature = "enable-feature-vhdx") { - features.push("--enable-vhdx".to_string()) - } - if cfg!(feature = "enable-feature-vhost-crypto") { - features.push("--enable-vhost-crypto".to_string()) - } - if cfg!(feature = "enable-feature-vhost-kernel") { - features.push("--enable-vhost-kernel".to_string()) - } - if cfg!(feature = "enable-feature-vhost-net") { - features.push("--enable-vhost-net".to_string()) - } - if cfg!(feature = "enable-feature-vhost-user") { - features.push("--enable-vhost-user".to_string()) - } - if cfg!(feature = "enable-feature-vhost-user-blk-server") { - features.push("--enable-vhost-user-blk-server".to_string()) - } - if cfg!(feature = "enable-feature-vhost-vdpa") { - features.push("--enable-vhost-vdpa".to_string()) - } - if cfg!(feature = "enable-feature-virglrenderer") { - features.push("--enable-virglrenderer".to_string()) - } - if cfg!(feature = "enable-feature-virtfs") { - features.push("--enable-virtfs".to_string()) - } - if cfg!(feature = "enable-feature-virtfs-proxy-helper") { - features.push("--enable-virtfs-proxy-helper".to_string()) - } - if cfg!(feature = "enable-feature-vmdk") { - features.push("--enable-vmdk".to_string()) - } - if cfg!(feature = "enable-feature-vmnet") { - features.push("--enable-vmnet".to_string()) - } - if cfg!(feature = "enable-feature-vnc") { - features.push("--enable-vnc".to_string()) - } - if cfg!(feature = "enable-feature-vnc-jpeg") { - features.push("--enable-vnc-jpeg".to_string()) - } - if cfg!(feature = "enable-feature-vnc-sasl") { - features.push("--enable-vnc-sasl".to_string()) - } - if cfg!(feature = "enable-feature-vpc") { - features.push("--enable-vpc".to_string()) - } - if cfg!(feature = "enable-feature-vte") { - features.push("--enable-vte".to_string()) - } - if cfg!(feature = "enable-feature-vvfat") { - features.push("--enable-vvfat".to_string()) - } - if cfg!(feature = "enable-feature-whpx") { - features.push("--enable-whpx".to_string()) - } - if cfg!(feature = "enable-feature-xen") { - features.push("--enable-xen".to_string()) - } - if cfg!(feature = "enable-feature-xen-pci-passthrough") { - features.push("--enable-xen-pci-passthrough".to_string()) - } - if cfg!(feature = "enable-feature-xkbcommon") { - features.push("--enable-xkbcommon".to_string()) - } - if cfg!(feature = "enable-feature-zstd") { - features.push("--enable-zstd".to_string()) - } - if cfg!(feature = "enable-feature-system") { - features.push("--enable-system".to_string()) - } - if cfg!(feature = "enable-feature-user") { - features.push("--enable-user".to_string()) - } - if cfg!(feature = "enable-feature-linux-user") { - features.push("--enable-linux-user".to_string()) - } - if cfg!(feature = "enable-feature-bsd-user") { - features.push("--enable-bsd-user".to_string()) - } - if cfg!(feature = "enable-feature-pie") { - features.push("--enable-pie".to_string()) - } - if cfg!(feature = "enable-feature-debug-tcg") { - features.push("--enable-debug-tcg".to_string()) - } - - features - } - - pub fn from_features() -> Self { - let mut features = Vec::new(); - - features.push(Self::targets_from_features()); - features.push(Self::audio_drv_from_features()); - features.extend(Self::options_from_features()); - features.push(Self::trace_backends_from_features()); - features.push(Self::coroutine_backend_from_features()); - features.extend(Self::features_from_features()); - - Self(features) - } - - pub fn with_prefix(&mut self, prefix: &Path) -> &mut Self { - self.0.push(format!("--prefix={}", prefix.display())); - self - } - - pub fn as_args(&self) -> Vec { - self.0.clone() - } -} - -fn qemu_src_url() -> String { - format!("{}qemu-{}.tar.xz", QEMU_SRC_URL_BASE, QEMU_VERSION) -} - -fn out_dir() -> Result { - Ok(PathBuf::from( - var("OUT_DIR").map_err(|e| anyhow!("OUT_DIR not set: {e}"))?, - )) -} - -/// Download a URL to a destination, using a blocking request -fn download(url: &str, destination: &Path) -> Result<()> { - let mut response = get(url)?; - let mut file = OpenOptions::new() - .write(true) - .create(true) - .truncate(true) - .open(destination)?; - response.copy_to(&mut file)?; - Ok(()) -} - -/// Extract a tar.xz archive at a path to a destination -fn extract_txz(archive: &Path, destination: &Path) -> Result<()> { - let mut archive = File::open(archive)?; - let mut archive = XzDecoder::new(&mut archive); - let mut archive = Archive::new(&mut archive); - // Unpack archive, removing 1 leading path component - archive - .entries()? - .filter_map(|e| e.ok()) - .try_for_each(|mut e| { - let Ok(path) = e.path() else { - return Err(anyhow!("Failed to get path from archive entry")); - }; - let Some(prefix) = path.components().next() else { - return Err(anyhow!("Failed to get prefix from archive entry {path:?}")); - }; - let Ok(suffix) = path.strip_prefix(prefix) else { - return Err(anyhow!( - "Failed to strip prefix {prefix:?} from archive entry {path:?}" - )); - }; - e.unpack(destination.join(suffix)) - .map(|_| ()) - .map_err(|e| anyhow!(e)) - })?; - Ok(()) -} - -fn configure(build: &Path, src: &Path, prefix: &Path) -> Result<()> { - Command::new(src.join("configure")) - .current_dir(build) - .args(ConfigureArgs::from_features().with_prefix(prefix).as_args()) - .check() - .map(|_| ()) - .map_err(Error::from) -} - -fn make(build: &Path) -> Result<()> { - #[cfg(unix)] - Command::new("make") - .arg(format!("-j{}", num_cpus::get())) - .current_dir(build) - .check() - .map(|_| ()) - .map_err(Error::from) -} - -fn install(build: &Path) -> Result<()> { - #[cfg(unix)] - Command::new("make") - .arg("install") - .current_dir(build) - .check() - .map(|_| ()) - .map_err(Error::from) -} - -fn main() -> Result<()> { - if var("DOCS_RS").is_ok() { - println!("cargo:rustc-cfg=docs_rs"); - return Ok(()); - } - - let out_dir = out_dir()?; - let src_archive = out_dir.join(format!("qemu-{}.tar.xz", QEMU_VERSION)); - let src_dir = out_dir.join(format!("qemu-{}", QEMU_VERSION)); - let build_dir = out_dir.join("qemu-build"); - let install_dir = out_dir.join("qemu"); - - if !src_archive.exists() { - download(&qemu_src_url(), &src_archive)?; - } - - if !src_dir.exists() { - extract_txz(&src_archive, &src_dir)?; - } - - if !build_dir.exists() { - create_dir_all(&build_dir)?; - configure(&build_dir, &src_dir, &install_dir)?; - make(&build_dir)?; - } - - if !install_dir.exists() { - create_dir_all(&install_dir)?; - install(&build_dir)?; - } - - println!("cargo:rerun-if-changed=build.rs"); - - Ok(()) -} diff --git a/qemu/src/bin/qemu-aarch64.rs b/qemu/src/bin/qemu-aarch64.rs deleted file mode 100644 index 10c7b05..0000000 --- a/qemu/src/bin/qemu-aarch64.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-aarch64 - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_AARCH64_LINUX_USER; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-aarch64", QEMU_AARCH64_LINUX_USER) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-aarch64_be.rs b/qemu/src/bin/qemu-aarch64_be.rs deleted file mode 100644 index dc87450..0000000 --- a/qemu/src/bin/qemu-aarch64_be.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-aarch64_be - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_AARCH64_BE_LINUX_USER; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-aarch64_be", QEMU_AARCH64_BE_LINUX_USER) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-alpha.rs b/qemu/src/bin/qemu-alpha.rs deleted file mode 100644 index 2fa3a1a..0000000 --- a/qemu/src/bin/qemu-alpha.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-alpha - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_ALPHA_LINUX_USER; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-alpha", QEMU_ALPHA_LINUX_USER) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-arm.rs b/qemu/src/bin/qemu-arm.rs deleted file mode 100644 index 2e883e6..0000000 --- a/qemu/src/bin/qemu-arm.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-arm - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_ARM_LINUX_USER; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-arm", QEMU_ARM_LINUX_USER) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-armeb.rs b/qemu/src/bin/qemu-armeb.rs deleted file mode 100644 index dfc0cb1..0000000 --- a/qemu/src/bin/qemu-armeb.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-armeb - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_ARMEB_LINUX_USER; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-armeb", QEMU_ARMEB_LINUX_USER) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-cris.rs b/qemu/src/bin/qemu-cris.rs deleted file mode 100644 index 5e83bca..0000000 --- a/qemu/src/bin/qemu-cris.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-cris - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_CRIS_LINUX_USER; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-cris", QEMU_CRIS_LINUX_USER) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-hexagon.rs b/qemu/src/bin/qemu-hexagon.rs deleted file mode 100644 index 75fa8eb..0000000 --- a/qemu/src/bin/qemu-hexagon.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-hexagon - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_HEXAGON_LINUX_USER; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-hexagon", QEMU_HEXAGON_LINUX_USER) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-hppa.rs b/qemu/src/bin/qemu-hppa.rs deleted file mode 100644 index 344d2fd..0000000 --- a/qemu/src/bin/qemu-hppa.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-hppa - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_HPPA_LINUX_USER; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-hppa", QEMU_HPPA_LINUX_USER) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-i386.rs b/qemu/src/bin/qemu-i386.rs deleted file mode 100644 index ad56db4..0000000 --- a/qemu/src/bin/qemu-i386.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-i386 - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_I386_LINUX_USER; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-i386", QEMU_I386_LINUX_USER) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-loongarch64.rs b/qemu/src/bin/qemu-loongarch64.rs deleted file mode 100644 index 01813ae..0000000 --- a/qemu/src/bin/qemu-loongarch64.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-loongarch64 - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_LOONGARCH64_LINUX_USER; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-loongarch64", QEMU_LOONGARCH64_LINUX_USER) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-m68k.rs b/qemu/src/bin/qemu-m68k.rs deleted file mode 100644 index b1edfb3..0000000 --- a/qemu/src/bin/qemu-m68k.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-m68k - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_M68K_LINUX_USER; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-m68k", QEMU_M68K_LINUX_USER) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-microblaze.rs b/qemu/src/bin/qemu-microblaze.rs deleted file mode 100644 index 6851c73..0000000 --- a/qemu/src/bin/qemu-microblaze.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-microblaze - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_MICROBLAZE_LINUX_USER; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-microblaze", QEMU_MICROBLAZE_LINUX_USER) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-microblazeel.rs b/qemu/src/bin/qemu-microblazeel.rs deleted file mode 100644 index c7bac77..0000000 --- a/qemu/src/bin/qemu-microblazeel.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-microblazeel - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_MICROBLAZEEL_LINUX_USER; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-microblazeel", QEMU_MICROBLAZEEL_LINUX_USER) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-mips.rs b/qemu/src/bin/qemu-mips.rs deleted file mode 100644 index 86f7bbe..0000000 --- a/qemu/src/bin/qemu-mips.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-mips - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_MIPS_LINUX_USER; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-mips", QEMU_MIPS_LINUX_USER) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-mips64.rs b/qemu/src/bin/qemu-mips64.rs deleted file mode 100644 index cdf0956..0000000 --- a/qemu/src/bin/qemu-mips64.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-mips64 - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_MIPS64_LINUX_USER; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-mips64", QEMU_MIPS64_LINUX_USER) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-mips64el.rs b/qemu/src/bin/qemu-mips64el.rs deleted file mode 100644 index 0925f07..0000000 --- a/qemu/src/bin/qemu-mips64el.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-mips64el - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_MIPS64EL_LINUX_USER; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-mips64el", QEMU_MIPS64EL_LINUX_USER) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-mipsel.rs b/qemu/src/bin/qemu-mipsel.rs deleted file mode 100644 index 7e47ea8..0000000 --- a/qemu/src/bin/qemu-mipsel.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-mipsel - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_MIPSEL_LINUX_USER; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-mipsel", QEMU_MIPSEL_LINUX_USER) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-mipsn32.rs b/qemu/src/bin/qemu-mipsn32.rs deleted file mode 100644 index 086af66..0000000 --- a/qemu/src/bin/qemu-mipsn32.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-mipsn32 - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_MIPSN32_LINUX_USER; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-mipsn32", QEMU_MIPSN32_LINUX_USER) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-mipsn32el.rs b/qemu/src/bin/qemu-mipsn32el.rs deleted file mode 100644 index 2a8c071..0000000 --- a/qemu/src/bin/qemu-mipsn32el.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-mipsn32el - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_MIPSN32EL_LINUX_USER; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-mipsn32el", QEMU_MIPSN32EL_LINUX_USER) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-nios2.rs b/qemu/src/bin/qemu-nios2.rs deleted file mode 100644 index 4625330..0000000 --- a/qemu/src/bin/qemu-nios2.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-nios2 - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_NIOS2_LINUX_USER; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-nios2", QEMU_NIOS2_LINUX_USER) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-or1k.rs b/qemu/src/bin/qemu-or1k.rs deleted file mode 100644 index aed9b8b..0000000 --- a/qemu/src/bin/qemu-or1k.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-or1k - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_OR1K_LINUX_USER; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-or1k", QEMU_OR1K_LINUX_USER) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-ppc.rs b/qemu/src/bin/qemu-ppc.rs deleted file mode 100644 index d7cae0b..0000000 --- a/qemu/src/bin/qemu-ppc.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-ppc - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_PPC_LINUX_USER; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-ppc", QEMU_PPC_LINUX_USER) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-ppc64.rs b/qemu/src/bin/qemu-ppc64.rs deleted file mode 100644 index 1d6cb14..0000000 --- a/qemu/src/bin/qemu-ppc64.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-ppc64 - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_PPC64_LINUX_USER; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-ppc64", QEMU_PPC64_LINUX_USER) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-ppc64le.rs b/qemu/src/bin/qemu-ppc64le.rs deleted file mode 100644 index 289d7ff..0000000 --- a/qemu/src/bin/qemu-ppc64le.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-ppc64le - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_PPC64LE_LINUX_USER; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-ppc64le", QEMU_PPC64LE_LINUX_USER) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-riscv32.rs b/qemu/src/bin/qemu-riscv32.rs deleted file mode 100644 index 7d09760..0000000 --- a/qemu/src/bin/qemu-riscv32.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-riscv32 - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_RISCV32_LINUX_USER; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-riscv32", QEMU_RISCV32_LINUX_USER) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-riscv64.rs b/qemu/src/bin/qemu-riscv64.rs deleted file mode 100644 index ebe25e0..0000000 --- a/qemu/src/bin/qemu-riscv64.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-riscv64 - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_RISCV64_LINUX_USER; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-riscv64", QEMU_RISCV64_LINUX_USER) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-s390x.rs b/qemu/src/bin/qemu-s390x.rs deleted file mode 100644 index c569e48..0000000 --- a/qemu/src/bin/qemu-s390x.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-s390x - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_S390X_LINUX_USER; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-s390x", QEMU_S390X_LINUX_USER) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-sh4.rs b/qemu/src/bin/qemu-sh4.rs deleted file mode 100644 index 991cabf..0000000 --- a/qemu/src/bin/qemu-sh4.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-sh4 - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_SH4_LINUX_USER; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-sh4", QEMU_SH4_LINUX_USER) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-sh4eb.rs b/qemu/src/bin/qemu-sh4eb.rs deleted file mode 100644 index e250d21..0000000 --- a/qemu/src/bin/qemu-sh4eb.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-sh4eb - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_SH4EB_LINUX_USER; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-sh4eb", QEMU_SH4EB_LINUX_USER) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-sparc.rs b/qemu/src/bin/qemu-sparc.rs deleted file mode 100644 index 838d3b1..0000000 --- a/qemu/src/bin/qemu-sparc.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-sparc - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_SPARC_LINUX_USER; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-sparc", QEMU_SPARC_LINUX_USER) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-sparc32plus.rs b/qemu/src/bin/qemu-sparc32plus.rs deleted file mode 100644 index 1165670..0000000 --- a/qemu/src/bin/qemu-sparc32plus.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-sparc32plus - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_SPARC32PLUS_LINUX_USER; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-sparc32plus", QEMU_SPARC32PLUS_LINUX_USER) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-sparc64.rs b/qemu/src/bin/qemu-sparc64.rs deleted file mode 100644 index 01b44d1..0000000 --- a/qemu/src/bin/qemu-sparc64.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-sparc64 - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_SPARC64_LINUX_USER; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-sparc64", QEMU_SPARC64_LINUX_USER) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-system-aarch64.rs b/qemu/src/bin/qemu-system-aarch64.rs deleted file mode 100644 index f91b5c4..0000000 --- a/qemu/src/bin/qemu-system-aarch64.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-system-aarch64 - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_AARCH64_SOFTMMU; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-system-aarch64", QEMU_AARCH64_SOFTMMU) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-system-alpha.rs b/qemu/src/bin/qemu-system-alpha.rs deleted file mode 100644 index 03b3059..0000000 --- a/qemu/src/bin/qemu-system-alpha.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-system-alpha - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_ALPHA_SOFTMMU; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-system-alpha", QEMU_ALPHA_SOFTMMU) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-system-arm.rs b/qemu/src/bin/qemu-system-arm.rs deleted file mode 100644 index ebe765d..0000000 --- a/qemu/src/bin/qemu-system-arm.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-system-arm - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_ARM_SOFTMMU; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-system-arm", QEMU_ARM_SOFTMMU) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-system-avr.rs b/qemu/src/bin/qemu-system-avr.rs deleted file mode 100644 index 6f6eccf..0000000 --- a/qemu/src/bin/qemu-system-avr.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-system-avr - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_AVR_SOFTMMU; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-system-avr", QEMU_AVR_SOFTMMU) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-system-cris.rs b/qemu/src/bin/qemu-system-cris.rs deleted file mode 100644 index f12e882..0000000 --- a/qemu/src/bin/qemu-system-cris.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-system-cris - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_CRIS_SOFTMMU; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-system-cris", QEMU_CRIS_SOFTMMU) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-system-hppa.rs b/qemu/src/bin/qemu-system-hppa.rs deleted file mode 100644 index 47d1d5d..0000000 --- a/qemu/src/bin/qemu-system-hppa.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-system-hppa - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_HPPA_SOFTMMU; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-system-hppa", QEMU_HPPA_SOFTMMU) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-system-i386.rs b/qemu/src/bin/qemu-system-i386.rs deleted file mode 100644 index 8eea2e2..0000000 --- a/qemu/src/bin/qemu-system-i386.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-system-i386 - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_I386_SOFTMMU; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-system-i386", QEMU_I386_SOFTMMU) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-system-loongarch64.rs b/qemu/src/bin/qemu-system-loongarch64.rs deleted file mode 100644 index 6a85f9b..0000000 --- a/qemu/src/bin/qemu-system-loongarch64.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-system-loongarch64 - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_LOONGARCH64_SOFTMMU; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-system-loongarch64", QEMU_LOONGARCH64_SOFTMMU) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-system-m68k.rs b/qemu/src/bin/qemu-system-m68k.rs deleted file mode 100644 index 3e5d803..0000000 --- a/qemu/src/bin/qemu-system-m68k.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-system-m68k - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_M68K_SOFTMMU; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-system-m68k", QEMU_M68K_SOFTMMU) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-system-microblaze.rs b/qemu/src/bin/qemu-system-microblaze.rs deleted file mode 100644 index aedd4b4..0000000 --- a/qemu/src/bin/qemu-system-microblaze.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-system-microblaze - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_MICROBLAZE_SOFTMMU; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-system-microblaze", QEMU_MICROBLAZE_SOFTMMU) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-system-microblazeel.rs b/qemu/src/bin/qemu-system-microblazeel.rs deleted file mode 100644 index 8f891ab..0000000 --- a/qemu/src/bin/qemu-system-microblazeel.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-system-microblazeel - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_MICROBLAZEEL_SOFTMMU; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-system-microblazeel", QEMU_MICROBLAZEEL_SOFTMMU) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-system-mips.rs b/qemu/src/bin/qemu-system-mips.rs deleted file mode 100644 index d3c4368..0000000 --- a/qemu/src/bin/qemu-system-mips.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-system-mips - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_MIPS_SOFTMMU; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-system-mips", QEMU_MIPS_SOFTMMU) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-system-mips64.rs b/qemu/src/bin/qemu-system-mips64.rs deleted file mode 100644 index 2d00cff..0000000 --- a/qemu/src/bin/qemu-system-mips64.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-system-mips64 - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_MIPS64_SOFTMMU; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-system-mips64", QEMU_MIPS64_SOFTMMU) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-system-mips64el.rs b/qemu/src/bin/qemu-system-mips64el.rs deleted file mode 100644 index c77e9d1..0000000 --- a/qemu/src/bin/qemu-system-mips64el.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-system-mips64el - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_MIPS64EL_SOFTMMU; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-system-mips64el", QEMU_MIPS64EL_SOFTMMU) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-system-mipsel.rs b/qemu/src/bin/qemu-system-mipsel.rs deleted file mode 100644 index 30747bf..0000000 --- a/qemu/src/bin/qemu-system-mipsel.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-system-mipsel - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_MIPSEL_SOFTMMU; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-system-mipsel", QEMU_MIPSEL_SOFTMMU) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-system-nios2.rs b/qemu/src/bin/qemu-system-nios2.rs deleted file mode 100644 index a46817d..0000000 --- a/qemu/src/bin/qemu-system-nios2.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-system-nios2 - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_NIOS2_SOFTMMU; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-system-nios2", QEMU_NIOS2_SOFTMMU) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-system-or1k.rs b/qemu/src/bin/qemu-system-or1k.rs deleted file mode 100644 index e34e4a8..0000000 --- a/qemu/src/bin/qemu-system-or1k.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-system-or1k - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_OR1K_SOFTMMU; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-system-or1k", QEMU_OR1K_SOFTMMU) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-system-ppc.rs b/qemu/src/bin/qemu-system-ppc.rs deleted file mode 100644 index 4fe1d09..0000000 --- a/qemu/src/bin/qemu-system-ppc.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-system-ppc - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_PPC_SOFTMMU; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-system-ppc", QEMU_PPC_SOFTMMU) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-system-ppc64.rs b/qemu/src/bin/qemu-system-ppc64.rs deleted file mode 100644 index dfcc28b..0000000 --- a/qemu/src/bin/qemu-system-ppc64.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-system-ppc64 - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_PPC64_SOFTMMU; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-system-ppc64", QEMU_PPC64_SOFTMMU) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-system-riscv32.rs b/qemu/src/bin/qemu-system-riscv32.rs deleted file mode 100644 index a306a96..0000000 --- a/qemu/src/bin/qemu-system-riscv32.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-system-riscv32 - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_RISCV32_SOFTMMU; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-system-riscv32", QEMU_RISCV32_SOFTMMU) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-system-riscv64.rs b/qemu/src/bin/qemu-system-riscv64.rs deleted file mode 100644 index bda9ae1..0000000 --- a/qemu/src/bin/qemu-system-riscv64.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-system-riscv64 - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_RISCV64_SOFTMMU; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-system-riscv64", QEMU_RISCV64_SOFTMMU) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-system-rx.rs b/qemu/src/bin/qemu-system-rx.rs deleted file mode 100644 index 9eb1120..0000000 --- a/qemu/src/bin/qemu-system-rx.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-system-rx - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_RX_SOFTMMU; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-system-rx", QEMU_RX_SOFTMMU) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-system-s390x.rs b/qemu/src/bin/qemu-system-s390x.rs deleted file mode 100644 index 2f0ba3e..0000000 --- a/qemu/src/bin/qemu-system-s390x.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-system-s390x - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_S390X_SOFTMMU; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-system-s390x", QEMU_S390X_SOFTMMU) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-system-sh4.rs b/qemu/src/bin/qemu-system-sh4.rs deleted file mode 100644 index 3691555..0000000 --- a/qemu/src/bin/qemu-system-sh4.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-system-sh4 - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_SH4_SOFTMMU; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-system-sh4", QEMU_SH4_SOFTMMU) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-system-sh4eb.rs b/qemu/src/bin/qemu-system-sh4eb.rs deleted file mode 100644 index b3acf8a..0000000 --- a/qemu/src/bin/qemu-system-sh4eb.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-system-sh4eb - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_SH4EB_SOFTMMU; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-system-sh4eb", QEMU_SH4EB_SOFTMMU) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-system-sparc.rs b/qemu/src/bin/qemu-system-sparc.rs deleted file mode 100644 index d2bb015..0000000 --- a/qemu/src/bin/qemu-system-sparc.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-system-sparc - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_SPARC_SOFTMMU; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-system-sparc", QEMU_SPARC_SOFTMMU) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-system-sparc64.rs b/qemu/src/bin/qemu-system-sparc64.rs deleted file mode 100644 index c8b211b..0000000 --- a/qemu/src/bin/qemu-system-sparc64.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-system-sparc64 - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_SPARC64_SOFTMMU; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-system-sparc64", QEMU_SPARC64_SOFTMMU) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-system-tricore.rs b/qemu/src/bin/qemu-system-tricore.rs deleted file mode 100644 index 416e58c..0000000 --- a/qemu/src/bin/qemu-system-tricore.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-system-tricore - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_TRICORE_SOFTMMU; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-system-tricore", QEMU_TRICORE_SOFTMMU) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-system-x86_64.rs b/qemu/src/bin/qemu-system-x86_64.rs deleted file mode 100644 index ecfc891..0000000 --- a/qemu/src/bin/qemu-system-x86_64.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-system-x86_64 - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_X86_64_SOFTMMU; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-system-x86_64", QEMU_X86_64_SOFTMMU) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-system-xtensa.rs b/qemu/src/bin/qemu-system-xtensa.rs deleted file mode 100644 index 2bc7b0e..0000000 --- a/qemu/src/bin/qemu-system-xtensa.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-system-xtensa - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_XTENSA_SOFTMMU; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-system-xtensa", QEMU_XTENSA_SOFTMMU) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-system-xtensaeb.rs b/qemu/src/bin/qemu-system-xtensaeb.rs deleted file mode 100644 index 20d7a39..0000000 --- a/qemu/src/bin/qemu-system-xtensaeb.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-system-xtensaeb - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_XTENSAEB_SOFTMMU; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-system-xtensaeb", QEMU_XTENSAEB_SOFTMMU) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-x86_64.rs b/qemu/src/bin/qemu-x86_64.rs deleted file mode 100644 index 7926648..0000000 --- a/qemu/src/bin/qemu-x86_64.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-x86_64 - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_X86_64_LINUX_USER; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-x86_64", QEMU_X86_64_LINUX_USER) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-xtensa.rs b/qemu/src/bin/qemu-xtensa.rs deleted file mode 100644 index 0c61d50..0000000 --- a/qemu/src/bin/qemu-xtensa.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-xtensa - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_XTENSA_LINUX_USER; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-xtensa", QEMU_XTENSA_LINUX_USER) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/bin/qemu-xtensaeb.rs b/qemu/src/bin/qemu-xtensaeb.rs deleted file mode 100644 index a30ab02..0000000 --- a/qemu/src/bin/qemu-xtensaeb.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for qemu-xtensaeb - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_XTENSAEB_LINUX_USER; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("qemu-xtensaeb", QEMU_XTENSAEB_LINUX_USER) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file diff --git a/qemu/src/lib.rs b/qemu/src/lib.rs deleted file mode 100644 index 92e1d36..0000000 --- a/qemu/src/lib.rs +++ /dev/null @@ -1,360 +0,0 @@ -//! Qemu library! -//! -//! This library provides a way to access QEMU binaries for all supported architectures -//! from rust code by wrapping the QEMU build system and then giving you binaries as -//! big constant byte arrays. Stay with me, this is a good way to do this! For example, -//! if you want to distributed a QEMU plugin written in rust, you can use this library -//! to build a plugin-supported QEMU binary and distribute it directly along with your -//! plugin as a rust crate. -//! -//! For very simple examples, see the binariesnamed `qemu-` in this workspace. -//! -//! In addition, if you want to do wild stuff that "doesn't circumvent the GPL", you can build -//! a debug binary, use something like [goblin](https://github.com/m4b/goblin) to figure out -//! where to hook, bytepatch the binary, then run it with your hooks. Is that insane? Maybe, -//! but you can do it, and it's a lot more efficient to just have the binary as bytes to -//! do so. -//! -//! To use, just configure your feature flags appropriately (see the README) and then use -//! one of the `QEMU_` constants here to obtain your binary. Then, you can either -//! write it to disk and run it, or you can be very efficient and use something like -//! [memfd-exec](https://crates.io/crates/memfd-exec) to run it from memory directly, or on -//! a separate thread, whatever! -//! -//! To install with binaries, `cargo install qemu --features=binaries,plugins,lto` - -pub const QEMU_VERSION: &str = "9.0.0"; - -#[cfg(all(feature = "aarch64-linux-user", not(docs_rs)))] -/// QEMU binary for qemu-aarch64 -pub const QEMU_AARCH64_LINUX_USER: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-aarch64")); - -#[cfg(all(feature = "aarch64_be-linux-user", not(docs_rs)))] -/// QEMU binary for qemu-aarch64_be -pub const QEMU_AARCH64_BE_LINUX_USER: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-aarch64_be")); - -#[cfg(all(feature = "alpha-linux-user", not(docs_rs)))] -/// QEMU binary for qemu-alpha -pub const QEMU_ALPHA_LINUX_USER: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-alpha")); - -#[cfg(all(feature = "arm-linux-user", not(docs_rs)))] -/// QEMU binary for qemu-arm -pub const QEMU_ARM_LINUX_USER: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-arm")); - -#[cfg(all(feature = "armeb-linux-user", not(docs_rs)))] -/// QEMU binary for qemu-armeb -pub const QEMU_ARMEB_LINUX_USER: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-armeb")); - -#[cfg(all(feature = "cris-linux-user", not(docs_rs)))] -/// QEMU binary for qemu-cris -pub const QEMU_CRIS_LINUX_USER: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-cris")); - -#[cfg(all(feature = "hexagon-linux-user", not(docs_rs)))] -/// QEMU binary for qemu-hexagon -pub const QEMU_HEXAGON_LINUX_USER: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-hexagon")); - -#[cfg(all(feature = "hppa-linux-user", not(docs_rs)))] -/// QEMU binary for qemu-hppa -pub const QEMU_HPPA_LINUX_USER: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-hppa")); - -#[cfg(all(feature = "i386-linux-user", not(docs_rs)))] -/// QEMU binary for qemu-i386 -pub const QEMU_I386_LINUX_USER: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-i386")); - -#[cfg(all(feature = "loongarch64-linux-user", not(docs_rs)))] -/// QEMU binary for qemu-loongarch64 -pub const QEMU_LOONGARCH64_LINUX_USER: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-loongarch64")); - -#[cfg(all(feature = "m68k-linux-user", not(docs_rs)))] -/// QEMU binary for qemu-m68k -pub const QEMU_M68K_LINUX_USER: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-m68k")); - -#[cfg(all(feature = "microblaze-linux-user", not(docs_rs)))] -/// QEMU binary for qemu-microblaze -pub const QEMU_MICROBLAZE_LINUX_USER: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-microblaze")); - -#[cfg(all(feature = "microblazeel-linux-user", not(docs_rs)))] -/// QEMU binary for qemu-microblazeel -pub const QEMU_MICROBLAZEEL_LINUX_USER: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-microblazeel")); - -#[cfg(all(feature = "mips-linux-user", not(docs_rs)))] -/// QEMU binary for qemu-mips -pub const QEMU_MIPS_LINUX_USER: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-mips")); - -#[cfg(all(feature = "mips64-linux-user", not(docs_rs)))] -/// QEMU binary for qemu-mips64 -pub const QEMU_MIPS64_LINUX_USER: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-mips64")); - -#[cfg(all(feature = "mips64el-linux-user", not(docs_rs)))] -/// QEMU binary for qemu-mips64el -pub const QEMU_MIPS64EL_LINUX_USER: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-mips64el")); - -#[cfg(all(feature = "mipsel-linux-user", not(docs_rs)))] -/// QEMU binary for qemu-mipsel -pub const QEMU_MIPSEL_LINUX_USER: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-mipsel")); - -#[cfg(all(feature = "mipsn32-linux-user", not(docs_rs)))] -/// QEMU binary for qemu-mipsn32 -pub const QEMU_MIPSN32_LINUX_USER: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-mipsn32")); - -#[cfg(all(feature = "mipsn32el-linux-user", not(docs_rs)))] -/// QEMU binary for qemu-mipsn32el -pub const QEMU_MIPSN32EL_LINUX_USER: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-mipsn32el")); - -#[cfg(all(feature = "nios2-linux-user", not(docs_rs)))] -/// QEMU binary for qemu-nios2 -pub const QEMU_NIOS2_LINUX_USER: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-nios2")); - -#[cfg(all(feature = "or1k-linux-user", not(docs_rs)))] -/// QEMU binary for qemu-or1k -pub const QEMU_OR1K_LINUX_USER: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-or1k")); - -#[cfg(all(feature = "ppc-linux-user", not(docs_rs)))] -/// QEMU binary for qemu-ppc -pub const QEMU_PPC_LINUX_USER: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-ppc")); - -#[cfg(all(feature = "ppc64-linux-user", not(docs_rs)))] -/// QEMU binary for qemu-ppc64 -pub const QEMU_PPC64_LINUX_USER: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-ppc64")); - -#[cfg(all(feature = "ppc64le-linux-user", not(docs_rs)))] -/// QEMU binary for qemu-ppc64le -pub const QEMU_PPC64LE_LINUX_USER: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-ppc64le")); - -#[cfg(all(feature = "riscv32-linux-user", not(docs_rs)))] -/// QEMU binary for qemu-riscv32 -pub const QEMU_RISCV32_LINUX_USER: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-riscv32")); - -#[cfg(all(feature = "riscv64-linux-user", not(docs_rs)))] -/// QEMU binary for qemu-riscv64 -pub const QEMU_RISCV64_LINUX_USER: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-riscv64")); - -#[cfg(all(feature = "s390x-linux-user", not(docs_rs)))] -/// QEMU binary for qemu-s390x -pub const QEMU_S390X_LINUX_USER: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-s390x")); - -#[cfg(all(feature = "sh4-linux-user", not(docs_rs)))] -/// QEMU binary for qemu-sh4 -pub const QEMU_SH4_LINUX_USER: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-sh4")); - -#[cfg(all(feature = "sh4eb-linux-user", not(docs_rs)))] -/// QEMU binary for qemu-sh4eb -pub const QEMU_SH4EB_LINUX_USER: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-sh4eb")); - -#[cfg(all(feature = "sparc-linux-user", not(docs_rs)))] -/// QEMU binary for qemu-sparc -pub const QEMU_SPARC_LINUX_USER: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-sparc")); - -#[cfg(all(feature = "sparc32plus-linux-user", not(docs_rs)))] -/// QEMU binary for qemu-sparc32plus -pub const QEMU_SPARC32PLUS_LINUX_USER: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-sparc32plus")); - -#[cfg(all(feature = "sparc64-linux-user", not(docs_rs)))] -/// QEMU binary for qemu-sparc64 -pub const QEMU_SPARC64_LINUX_USER: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-sparc64")); - -#[cfg(all(feature = "x86_64-linux-user", not(docs_rs)))] -/// QEMU binary for qemu-x86_64 -pub const QEMU_X86_64_LINUX_USER: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-x86_64")); - -#[cfg(all(feature = "xtensa-linux-user", not(docs_rs)))] -/// QEMU binary for qemu-xtensa -pub const QEMU_XTENSA_LINUX_USER: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-xtensa")); - -#[cfg(all(feature = "xtensaeb-linux-user", not(docs_rs)))] -/// QEMU binary for qemu-xtensaeb -pub const QEMU_XTENSAEB_LINUX_USER: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-xtensaeb")); - -#[cfg(all(feature = "aarch64-softmmu", not(docs_rs)))] -/// QEMU binary for qemu-system-aarch64 -pub const QEMU_AARCH64_SOFTMMU: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-system-aarch64")); - -#[cfg(all(feature = "alpha-softmmu", not(docs_rs)))] -/// QEMU binary for qemu-system-alpha -pub const QEMU_ALPHA_SOFTMMU: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-system-alpha")); - -#[cfg(all(feature = "arm-softmmu", not(docs_rs)))] -/// QEMU binary for qemu-system-arm -pub const QEMU_ARM_SOFTMMU: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-system-arm")); - -#[cfg(all(feature = "avr-softmmu", not(docs_rs)))] -/// QEMU binary for qemu-system-avr -pub const QEMU_AVR_SOFTMMU: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-system-avr")); - -#[cfg(all(feature = "cris-softmmu", not(docs_rs)))] -/// QEMU binary for qemu-system-cris -pub const QEMU_CRIS_SOFTMMU: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-system-cris")); - -#[cfg(all(feature = "hppa-softmmu", not(docs_rs)))] -/// QEMU binary for qemu-system-hppa -pub const QEMU_HPPA_SOFTMMU: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-system-hppa")); - -#[cfg(all(feature = "i386-softmmu", not(docs_rs)))] -/// QEMU binary for qemu-system-i386 -pub const QEMU_I386_SOFTMMU: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-system-i386")); - -#[cfg(all(feature = "loongarch64-softmmu", not(docs_rs)))] -/// QEMU binary for qemu-system-loongarch64 -pub const QEMU_LOONGARCH64_SOFTMMU: &[u8] = include_bytes!(concat!( - env!("OUT_DIR"), - "/qemu/bin/qemu-system-loongarch64" -)); - -#[cfg(all(feature = "m68k-softmmu", not(docs_rs)))] -/// QEMU binary for qemu-system-m68k -pub const QEMU_M68K_SOFTMMU: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-system-m68k")); - -#[cfg(all(feature = "microblaze-softmmu", not(docs_rs)))] -/// QEMU binary for qemu-system-microblaze -pub const QEMU_MICROBLAZE_SOFTMMU: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-system-microblaze")); - -#[cfg(all(feature = "microblazeel-softmmu", not(docs_rs)))] -/// QEMU binary for qemu-system-microblazeel -pub const QEMU_MICROBLAZEEL_SOFTMMU: &[u8] = include_bytes!(concat!( - env!("OUT_DIR"), - "/qemu/bin/qemu-system-microblazeel" -)); - -#[cfg(all(feature = "mips-softmmu", not(docs_rs)))] -/// QEMU binary for qemu-system-mips -pub const QEMU_MIPS_SOFTMMU: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-system-mips")); - -#[cfg(all(feature = "mips64-softmmu", not(docs_rs)))] -/// QEMU binary for qemu-system-mips64 -pub const QEMU_MIPS64_SOFTMMU: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-system-mips64")); - -#[cfg(all(feature = "mips64el-softmmu", not(docs_rs)))] -/// QEMU binary for qemu-system-mips64el -pub const QEMU_MIPS64EL_SOFTMMU: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-system-mips64el")); - -#[cfg(all(feature = "mipsel-softmmu", not(docs_rs)))] -/// QEMU binary for qemu-system-mipsel -pub const QEMU_MIPSEL_SOFTMMU: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-system-mipsel")); - -#[cfg(all(feature = "nios2-softmmu", not(docs_rs)))] -/// QEMU binary for qemu-system-nios2 -pub const QEMU_NIOS2_SOFTMMU: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-system-nios2")); - -#[cfg(all(feature = "or1k-softmmu", not(docs_rs)))] -/// QEMU binary for qemu-system-or1k -pub const QEMU_OR1K_SOFTMMU: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-system-or1k")); - -#[cfg(all(feature = "ppc-softmmu", not(docs_rs)))] -/// QEMU binary for qemu-system-ppc -pub const QEMU_PPC_SOFTMMU: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-system-ppc")); - -#[cfg(all(feature = "ppc64-softmmu", not(docs_rs)))] -/// QEMU binary for qemu-system-ppc64 -pub const QEMU_PPC64_SOFTMMU: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-system-ppc64")); - -#[cfg(all(feature = "riscv32-softmmu", not(docs_rs)))] -/// QEMU binary for qemu-system-riscv32 -pub const QEMU_RISCV32_SOFTMMU: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-system-riscv32")); - -#[cfg(all(feature = "riscv64-softmmu", not(docs_rs)))] -/// QEMU binary for qemu-system-riscv64 -pub const QEMU_RISCV64_SOFTMMU: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-system-riscv64")); - -#[cfg(all(feature = "rx-softmmu", not(docs_rs)))] -/// QEMU binary for qemu-system-rx -pub const QEMU_RX_SOFTMMU: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-system-rx")); - -#[cfg(all(feature = "s390x-softmmu", not(docs_rs)))] -/// QEMU binary for qemu-system-s390x -pub const QEMU_S390X_SOFTMMU: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-system-s390x")); - -#[cfg(all(feature = "sh4-softmmu", not(docs_rs)))] -/// QEMU binary for qemu-system-sh4 -pub const QEMU_SH4_SOFTMMU: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-system-sh4")); - -#[cfg(all(feature = "sh4eb-softmmu", not(docs_rs)))] -/// QEMU binary for qemu-system-sh4eb -pub const QEMU_SH4EB_SOFTMMU: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-system-sh4eb")); - -#[cfg(all(feature = "sparc-softmmu", not(docs_rs)))] -/// QEMU binary for qemu-system-sparc -pub const QEMU_SPARC_SOFTMMU: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-system-sparc")); - -#[cfg(all(feature = "sparc64-softmmu", not(docs_rs)))] -/// QEMU binary for qemu-system-sparc64 -pub const QEMU_SPARC64_SOFTMMU: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-system-sparc64")); - -#[cfg(all(feature = "tricore-softmmu", not(docs_rs)))] -/// QEMU binary for qemu-system-tricore -pub const QEMU_TRICORE_SOFTMMU: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-system-tricore")); - -#[cfg(all(feature = "x86_64-softmmu", not(docs_rs)))] -/// QEMU binary for qemu-system-x86_64 -pub const QEMU_X86_64_SOFTMMU: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-system-x86_64")); - -#[cfg(all(feature = "xtensa-softmmu", not(docs_rs)))] -/// QEMU binary for qemu-system-xtensa -pub const QEMU_XTENSA_SOFTMMU: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-system-xtensa")); - -#[cfg(all(feature = "xtensaeb-softmmu", not(docs_rs)))] -/// QEMU binary for qemu-system-xtensaeb -pub const QEMU_XTENSAEB_SOFTMMU: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/qemu/bin/qemu-system-xtensaeb")); diff --git a/qemu/templates/README.md b/qemu/templates/README.md deleted file mode 100644 index 469b5eb..0000000 --- a/qemu/templates/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# Templates - -Template files for generating bins. Generated binary files with: - -```sh -grep "required-features" Cargo.toml | awk '{print $4}' | grep -oE '(-|_|[a-z0-9])+' | xargs -i bash -c 'BINNAME=$(printf {} | sed -r '"'"'s/(.*)-softmmu/qemu-system-\1/'"'"' | sed -r '"'"'s/(.*)-linux-user/qemu-\1/'"'"'); TARGET={}; CONSTNAME=$(printf {} | awk '"'"'{ gsub(/-/, "_"); print "QEMU_"toupper($0); }'"'"'); cp templates/bin.rs src/bin/$BINNAME.rs; sed -i "s/QEMU_BINARY_NAME/$BINNAME/g" src/bin/$BINNAME.rs; sed -i "s/QEMU_BINARY_CONST/$CONSTNAME/g" src/bin/$BINNAME.rs' -``` \ No newline at end of file diff --git a/qemu/templates/bin.rs b/qemu/templates/bin.rs deleted file mode 100644 index 61bf6bd..0000000 --- a/qemu/templates/bin.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Executable binary for QEMU_BINARY_NAME - -use memfd_exec::{MemFdExecutable, Stdio}; -use qemu::QEMU_BINARY_CONST; -use std::env::args; - -fn main() { - let mut args: Vec = args().collect(); - - args.remove(0); - - MemFdExecutable::new("QEMU_BINARY_NAME", QEMU_BINARY_CONST) - .args(args) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .spawn() - .expect("Failed to start QEMU process") - .wait() - .expect("QEMU process failed"); -} \ No newline at end of file