Skip to content

Commit

Permalink
Merge pull request #7 from novafacing/8.2.0-v1
Browse files Browse the repository at this point in the history
Support 8.2.0
  • Loading branch information
novafacing authored Jan 10, 2024
2 parents 0d2b042 + c57db71 commit 2d1c40d
Show file tree
Hide file tree
Showing 11 changed files with 211 additions and 99 deletions.
5 changes: 3 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,9 @@ jobs:
name: Build and Test Plugins (Windows)
runs-on: windows-latest
env:
# QEMU 8.1.0
QEMU_URL: "https://qemu.weilnetz.de/w64/2023/qemu-w64-setup-20230822.exe"
# QEMU 8.2.0
# NOTE: This installer does not work headless
# QEMU_URL: "https://qemu.weilnetz.de/w64/2023/qemu-w64-setup-20231224.exe"
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"

Expand Down
8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ license = "GPL-2.0-only"
publish = true
readme = "README.md"
repository = "https://github.com/novafacing/qemu-rs"
version = "8.1.3-v4"
version = "8.2.0-v1"

[workspace]
resolver = "2"
Expand All @@ -23,6 +23,6 @@ members = [
default-members = ["qemu-plugin", "qemu-plugin-sys"]

[workspace.dependencies]
qemu-plugin-sys = { version = "8.1.3-v4", path = "qemu-plugin-sys" }
qemu-plugin = { version = "8.1.3-v4", path = "qemu-plugin" }
qemu = { version = "8.1.3-v4", path = "qemu" }
qemu-plugin-sys = { version = "8.2.0-v1", path = "qemu-plugin-sys" }
qemu-plugin = { version = "8.2.0-v1", path = "qemu-plugin" }
qemu = { version = "8.2.0-v1", path = "qemu" }
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ 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@8.1.3-v3 --features=binaries
cargo install qemu@8.2.0-v1 --features=binaries
```

On some systems, particularly BTRFS systems, `/tmp` may not be large enough for the
Expand Down
2 changes: 1 addition & 1 deletion qemu-plugin-sys/generate-bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use tar::Archive;
use xz2::read::XzDecoder;

const QEMU_SRC_URL_BASE: &str = "https://download.qemu.org/";
const QEMU_VERSION: &str = "8.1.3";
const QEMU_VERSION: &str = "8.2.0";

fn qemu_src_url() -> String {
format!("{}qemu-{}.tar.xz", QEMU_SRC_URL_BASE, QEMU_VERSION)
Expand Down
2 changes: 1 addition & 1 deletion qemu-plugin/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ version.workspace = true
[dependencies]
anyhow = "1.0.75"
once_cell = "1.19.0"
qemu-plugin-sys = { version = "8.1.3-v3", workspace = true }
qemu-plugin-sys = { version = "8.2.0-v1", workspace = true }
thiserror = "1.0.51"

[target.'cfg(windows)'.dependencies.windows]
Expand Down
2 changes: 1 addition & 1 deletion qemu-plugin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ edition = "2021"
crate-type = ["cdylib"]

[dependencies]
qemu-plugin = "8.1.3-v1"
qemu-plugin = "8.2.0-v1"
anyhow = "1.0.75"
ffi = "0.1.0"
ctor = "0.2.6"
Expand Down
17 changes: 12 additions & 5 deletions qemu-plugin/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
//! crate-type = ["cdylib"]
//!
//! [dependencies]
//! qemu-plugin = "8.1.3-v1"
//! qemu-plugin = "8.2.0-v1"
//! anyhow = "1.0.75"
//! ffi = "0.1.0"
//! ctor = "0.2.6"
Expand Down Expand Up @@ -107,6 +107,14 @@ extern "C" {
}

#[cfg(windows)]
/// Define g_free, because on Windows we cannot delay link it
///
/// # Safety
///
/// `g_free` must *only* be used to deallocate values allocated with `g_malloc`, regardless of
/// its documented guarantees about wrapping the system allocator. QEMU plugin APIs which return
/// such values are documented to do so, and it is safe to call `g_free` on these values
/// provided they are not used afterward.
unsafe fn g_free(mem: *mut c_void) {
//TODO: We would really like to call g_free in the qemu binary here
//but we can't, because windows doesn't export symbols unless you explicitly export them
Expand All @@ -115,10 +123,9 @@ unsafe fn g_free(mem: *mut c_void) {
// NOTE: glib 2.46 g_malloc always uses system malloc implementation:
// https://docs.gtk.org/glib/func.mem_is_system_malloc.html
// So it is safe to call libc free to free a `g_malloc`-ed object
unsafe {
if !mem.is_null() {
free(mem)
}
if !mem.is_null() {
// SAFETY: `mem` is non-null.
unsafe { free(mem) }
}
}

Expand Down
58 changes: 46 additions & 12 deletions qemu-plugin/src/win_link_hook/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,58 @@
use windows::core::PCSTR;
use windows::Win32::Foundation::HMODULE;
use windows::Win32::System::LibraryLoader::GetModuleHandleA;
use windows::Win32::System::LibraryLoader::GetModuleHandleExA;
use windows::Win32::System::WindowsProgramming::DELAYLOAD_INFO;

type FailureHook = unsafe extern "C" fn(dli_notify: u32, pdli: DELAYLOAD_INFO) -> HMODULE;
/// The helper function for linker-supported delayed loading which is what actually
/// loads the DLL at runtime.
type DelayHook = unsafe extern "C" fn(dli_notify: DliNotify, pdli: DELAYLOAD_INFO) -> HMODULE;

#[no_mangle]
/// Callback invoked by Windows loader to complete linking against QEMU symbols
pub static __pfnDliFailureHook2: FailureHook = delaylink_hook;
/// Helper function invoked when failures occur in delay linking (as opposed to
/// notifications)
pub static __pfnDliFailureHook2: DelayHook = delaylink_hook;

extern "C" fn delaylink_hook(dli_notify: u32, pdli: DELAYLOAD_INFO) -> HMODULE {
if dli_notify == 3 {
#[repr(C)]
/// Delay load import hook notifications
///
enum DliNotify {
/// Used to bypass
DliNoteStartProcessing = 0,
/// Called just before LoadLibrary, can override w/ new HMODULE return val
DliNotePreLoadLibrary,
/// Called just before GetProcAddress, override w/ new FARPROC return value
DliNotePreGetProcAddress,
/// Failed to load library, fix it by
/// returning a valid HMODULE
DliFailLoadLib,
/// Failed to get proc address, fix it by
/// returning a valid FARPROC
DliFailGetProc,
/// Called after all processing is done, no bypass possible at this point except by
/// longjmp()/throw()/RaiseException.
DliNoteEndProcessing,
}

/// Helper function invoked when notifications or failures occur in delay linking
///
/// # Arguments
///
/// * `dli_notify` - The
extern "C" fn delaylink_hook(dli_notify: DliNotify, pdli: DELAYLOAD_INFO) -> HMODULE {
if let DliNotify::DliFailLoadLib = dli_notify {
// SAFETY: Conversion of `PCSTR` to String is not safe because it involves an unchecked
// nul-byte dependent `strcpy`. In this instance, it is safe because
let name = unsafe { pdli.TargetDllName.to_string() }.unwrap_or_default();
if name == "qemu.exe" {
match unsafe { GetModuleHandleA(PCSTR::null()) } {
Ok(h) => return h,
Err(e) => {
eprintln!("Error loading top level qemu module: {e:?}");
}
let mut module = HMODULE::default();

// NOTE: QEMU executables on windows are named qemu-system.*.exe
if name.starts_with("qemu") {
// SAFETY: Getting the module handle for NULL is safe and does not dereference any
// pointers except to write the `module` argument which we know is alive here.
match unsafe { GetModuleHandleExA(0, PCSTR::null(), &mut module as *mut HMODULE) } {
Ok(_) => return module,
Err(e) => panic!("Failed to open QEMU module: {e:?}"),
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions qemu/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ 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 = "8.1.3", features = ["qemu-aarch64"] }
qemu = { version = "8.2.0", features = ["qemu-aarch64"] }
```

```rust
Expand Down Expand Up @@ -115,7 +115,7 @@ to configure this crate as a dependency:
This will make the `qemu-x86_64` binary available.

```toml
qemu = { version = "8.1.3", features = ["qemu-x86_64"] }
qemu = { version = "8.2.0", features = ["qemu-x86_64"] }
```

### Install an optimized qemu-x86_64 usermode emulator
Expand All @@ -124,7 +124,7 @@ This will also make the `qemu-x86_64` binary available, but will strip and optim
with `lto`.

```toml
qemu = { version = "8.1.3", features = ["qemu-x86_64", "lto", "strip"]
qemu = { version = "8.2.0", features = ["qemu-x86_64", "lto", "strip"]
```

### Install qemu-system-arm emulator with customized options
Expand Down
2 changes: 1 addition & 1 deletion qemu/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use tar::Archive;
use xz2::read::XzDecoder;

const QEMU_SRC_URL_BASE: &str = "https://download.qemu.org/";
const QEMU_VERSION: &str = "8.1.3";
const QEMU_VERSION: &str = "8.2.0";

pub struct ConfigureArgs(Vec<String>);

Expand Down
Loading

0 comments on commit 2d1c40d

Please sign in to comment.