From 2302f1b35c6e706dc801ef096e41c1a062b3e66a Mon Sep 17 00:00:00 2001 From: Romain Malmain Date: Thu, 2 May 2024 15:17:35 +0200 Subject: [PATCH] Fix QEMU doc not building (again) (#2130) * fix doc not building. --- libafl_qemu/Cargo.toml | 1 + libafl_qemu/build_linux.rs | 39 ++- .../src/x86_64_stub_bindings.rs | 1 - .../runtime/libafl_qemu_stub_bindings.rs | 316 ++++++++++++++++++ libafl_qemu/src/command.rs | 2 +- 5 files changed, 341 insertions(+), 18 deletions(-) create mode 100644 libafl_qemu/runtime/libafl_qemu_stub_bindings.rs diff --git a/libafl_qemu/Cargo.toml b/libafl_qemu/Cargo.toml index 116607ed8e..3042f4537e 100644 --- a/libafl_qemu/Cargo.toml +++ b/libafl_qemu/Cargo.toml @@ -94,6 +94,7 @@ pyo3 = { version = "0.18", optional = true } document-features = { version = "0.2", optional = true } [build-dependencies] +libafl_qemu_build = { path = "./libafl_qemu_build", version = "0.12.0" } pyo3-build-config = { version = "0.18", optional = true } rustversion = "1.0" bindgen = "0.69" diff --git a/libafl_qemu/build_linux.rs b/libafl_qemu/build_linux.rs index ca521c671e..973c519dbe 100644 --- a/libafl_qemu/build_linux.rs +++ b/libafl_qemu/build_linux.rs @@ -14,21 +14,35 @@ pub fn build() { }) }; + let src_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); + let src_dir = PathBuf::from(src_dir); + + let out_dir = env::var("OUT_DIR").unwrap(); + let out_dir = PathBuf::from(&out_dir); + + let mut target_dir = out_dir.clone(); + target_dir.pop(); + target_dir.pop(); + target_dir.pop(); + let include_dir = target_dir.join("include"); let qemu_asan_guest = cfg!(all(feature = "build_libgasan", not(feature = "hexagon"))); let qemu_asan = cfg!(all(feature = "build_libqasan", not(feature = "hexagon"))); let libafl_qemu_hdr_name = "libafl_qemu.h"; - let exit_hdr_dir = PathBuf::from("runtime"); - let libafl_qemu_hdr = exit_hdr_dir.join(libafl_qemu_hdr_name); + let libafl_runtime_dir = src_dir.join("runtime"); + let libafl_qemu_hdr = libafl_runtime_dir.join(libafl_qemu_hdr_name); + + let runtime_bindings_file = out_dir.join("libafl_qemu_bindings.rs"); + let stub_runtime_bindings_file = src_dir.join("runtime/libafl_qemu_stub_bindings.rs"); println!("cargo:rustc-cfg=emulation_mode=\"{emulation_mode}\""); println!("cargo:rerun-if-env-changed=EMULATION_MODE"); println!("cargo:rerun-if-changed=build.rs"); println!("cargo:rerun-if-changed=build_linux.rs"); - println!("cargo:rerun-if-changed={}", exit_hdr_dir.display()); + println!("cargo:rerun-if-changed={}", libafl_runtime_dir.display()); let cpu_target = if cfg!(feature = "x86_64") { "x86_64".to_string() @@ -65,24 +79,15 @@ pub fn build() { String::new() }; - if std::env::var("DOCS_RS").is_ok() { + if env::var("DOCS_RS").is_ok() || cfg!(feature = "clippy") { + fs::copy(&stub_runtime_bindings_file, &runtime_bindings_file).expect("Could not copy stub bindings file"); return; // only build when we're not generating docs } - let out_dir = env::var("OUT_DIR").unwrap(); - let out_dir_path = Path::new(&out_dir); - let out_dir_path_buf = out_dir_path.to_path_buf(); - let mut target_dir = out_dir_path_buf.clone(); - target_dir.pop(); - target_dir.pop(); - target_dir.pop(); - let include_dir = target_dir.join("include"); - fs::create_dir_all(&include_dir).expect("Could not create include dir"); fs::copy(libafl_qemu_hdr.clone(), include_dir.join(libafl_qemu_hdr_name)).expect("Could not copy libafl_qemu.h to out directory."); - let binding_file = out_dir_path_buf.join("backdoor_bindings.rs"); bindgen::Builder::default() .derive_debug(true) .derive_default(true) @@ -95,9 +100,11 @@ pub fn build() { .header(libafl_qemu_hdr.display().to_string()) .generate() .expect("Exit bindings generation failed.") - .write_to_file(binding_file) + .write_to_file(&runtime_bindings_file) .expect("Could not write bindings."); + libafl_qemu_build::store_generated_content_if_different(&stub_runtime_bindings_file, fs::read(&runtime_bindings_file).expect("Could not read generated bindings file").as_slice()); + if (emulation_mode == "usermode") && (qemu_asan || qemu_asan_guest) { let qasan_dir = Path::new("libqasan"); let qasan_dir = fs::canonicalize(qasan_dir).unwrap(); @@ -108,7 +115,7 @@ pub fn build() { make.env("CFLAGS", "-DDEBUG=1"); } assert!(make - .current_dir(out_dir_path) + .current_dir(&out_dir) .env("CC", &cross_cc) .env("OUT_DIR", &target_dir) .arg("-C") diff --git a/libafl_qemu/libafl_qemu_sys/src/x86_64_stub_bindings.rs b/libafl_qemu/libafl_qemu_sys/src/x86_64_stub_bindings.rs index be87633126..c2eccb962f 100644 --- a/libafl_qemu/libafl_qemu_sys/src/x86_64_stub_bindings.rs +++ b/libafl_qemu/libafl_qemu_sys/src/x86_64_stub_bindings.rs @@ -2340,7 +2340,6 @@ pub type DeviceReset = ::std::option::Option = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::<__fsid_t>(), + 8usize, + concat!("Size of: ", stringify!(__fsid_t)) + ); + assert_eq!( + ::std::mem::align_of::<__fsid_t>(), + 4usize, + concat!("Alignment of ", stringify!(__fsid_t)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__val) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(__fsid_t), + "::", + stringify!(__val) + ) + ); +} +pub type __clock_t = ::std::os::raw::c_long; +pub type __rlim_t = ::std::os::raw::c_ulong; +pub type __rlim64_t = ::std::os::raw::c_ulong; +pub type __id_t = ::std::os::raw::c_uint; +pub type __time_t = ::std::os::raw::c_long; +pub type __useconds_t = ::std::os::raw::c_uint; +pub type __suseconds_t = ::std::os::raw::c_long; +pub type __suseconds64_t = ::std::os::raw::c_long; +pub type __daddr_t = ::std::os::raw::c_int; +pub type __key_t = ::std::os::raw::c_int; +pub type __clockid_t = ::std::os::raw::c_int; +pub type __timer_t = *mut ::std::os::raw::c_void; +pub type __blksize_t = ::std::os::raw::c_long; +pub type __blkcnt_t = ::std::os::raw::c_long; +pub type __blkcnt64_t = ::std::os::raw::c_long; +pub type __fsblkcnt_t = ::std::os::raw::c_ulong; +pub type __fsblkcnt64_t = ::std::os::raw::c_ulong; +pub type __fsfilcnt_t = ::std::os::raw::c_ulong; +pub type __fsfilcnt64_t = ::std::os::raw::c_ulong; +pub type __fsword_t = ::std::os::raw::c_long; +pub type __ssize_t = ::std::os::raw::c_long; +pub type __syscall_slong_t = ::std::os::raw::c_long; +pub type __syscall_ulong_t = ::std::os::raw::c_ulong; +pub type __loff_t = __off64_t; +pub type __caddr_t = *mut ::std::os::raw::c_char; +pub type __intptr_t = ::std::os::raw::c_long; +pub type __socklen_t = ::std::os::raw::c_uint; +pub type __sig_atomic_t = ::std::os::raw::c_int; +pub type int_least8_t = __int_least8_t; +pub type int_least16_t = __int_least16_t; +pub type int_least32_t = __int_least32_t; +pub type int_least64_t = __int_least64_t; +pub type uint_least8_t = __uint_least8_t; +pub type uint_least16_t = __uint_least16_t; +pub type uint_least32_t = __uint_least32_t; +pub type uint_least64_t = __uint_least64_t; +pub type int_fast8_t = ::std::os::raw::c_schar; +pub type int_fast16_t = ::std::os::raw::c_long; +pub type int_fast32_t = ::std::os::raw::c_long; +pub type int_fast64_t = ::std::os::raw::c_long; +pub type uint_fast8_t = ::std::os::raw::c_uchar; +pub type uint_fast16_t = ::std::os::raw::c_ulong; +pub type uint_fast32_t = ::std::os::raw::c_ulong; +pub type uint_fast64_t = ::std::os::raw::c_ulong; +pub type intmax_t = __intmax_t; +pub type uintmax_t = __uintmax_t; +pub type libafl_word = u64; +pub const LibaflQemuCommand_LIBAFL_QEMU_COMMAND_START_VIRT: LibaflQemuCommand = + LibaflQemuCommand(0); +pub const LibaflQemuCommand_LIBAFL_QEMU_COMMAND_START_PHYS: LibaflQemuCommand = + LibaflQemuCommand(1); +pub const LibaflQemuCommand_LIBAFL_QEMU_COMMAND_INPUT_VIRT: LibaflQemuCommand = + LibaflQemuCommand(2); +pub const LibaflQemuCommand_LIBAFL_QEMU_COMMAND_INPUT_PHYS: LibaflQemuCommand = + LibaflQemuCommand(3); +pub const LibaflQemuCommand_LIBAFL_QEMU_COMMAND_END: LibaflQemuCommand = LibaflQemuCommand(4); +pub const LibaflQemuCommand_LIBAFL_QEMU_COMMAND_SAVE: LibaflQemuCommand = LibaflQemuCommand(5); +pub const LibaflQemuCommand_LIBAFL_QEMU_COMMAND_LOAD: LibaflQemuCommand = LibaflQemuCommand(6); +pub const LibaflQemuCommand_LIBAFL_QEMU_COMMAND_VERSION: LibaflQemuCommand = LibaflQemuCommand(7); +pub const LibaflQemuCommand_LIBAFL_QEMU_COMMAND_VADDR_FILTER_ALLOW: LibaflQemuCommand = + LibaflQemuCommand(8); +impl ::std::ops::BitOr for LibaflQemuCommand { + type Output = Self; + #[inline] + fn bitor(self, other: Self) -> Self { + LibaflQemuCommand(self.0 | other.0) + } +} +impl ::std::ops::BitOrAssign for LibaflQemuCommand { + #[inline] + fn bitor_assign(&mut self, rhs: LibaflQemuCommand) { + self.0 |= rhs.0; + } +} +impl ::std::ops::BitAnd for LibaflQemuCommand { + type Output = Self; + #[inline] + fn bitand(self, other: Self) -> Self { + LibaflQemuCommand(self.0 & other.0) + } +} +impl ::std::ops::BitAndAssign for LibaflQemuCommand { + #[inline] + fn bitand_assign(&mut self, rhs: LibaflQemuCommand) { + self.0 &= rhs.0; + } +} +#[repr(transparent)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct LibaflQemuCommand(pub ::std::os::raw::c_uint); +pub use self::LibaflQemuCommand as LibaflExit; +pub const LibaflQemuEndStatus_LIBAFL_QEMU_END_UNKNOWN: LibaflQemuEndStatus = LibaflQemuEndStatus(0); +pub const LibaflQemuEndStatus_LIBAFL_QEMU_END_OK: LibaflQemuEndStatus = LibaflQemuEndStatus(1); +pub const LibaflQemuEndStatus_LIBAFL_QEMU_END_CRASH: LibaflQemuEndStatus = LibaflQemuEndStatus(2); +impl ::std::ops::BitOr for LibaflQemuEndStatus { + type Output = Self; + #[inline] + fn bitor(self, other: Self) -> Self { + LibaflQemuEndStatus(self.0 | other.0) + } +} +impl ::std::ops::BitOrAssign for LibaflQemuEndStatus { + #[inline] + fn bitor_assign(&mut self, rhs: LibaflQemuEndStatus) { + self.0 |= rhs.0; + } +} +impl ::std::ops::BitAnd for LibaflQemuEndStatus { + type Output = Self; + #[inline] + fn bitand(self, other: Self) -> Self { + LibaflQemuEndStatus(self.0 & other.0) + } +} +impl ::std::ops::BitAndAssign for LibaflQemuEndStatus { + #[inline] + fn bitand_assign(&mut self, rhs: LibaflQemuEndStatus) { + self.0 &= rhs.0; + } +} +#[repr(transparent)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct LibaflQemuEndStatus(pub ::std::os::raw::c_uint); +pub use self::LibaflQemuEndStatus as LibaflExitEndParams; +extern "C" { + pub fn _libafl_sync_exit_call0(action: libafl_word) -> libafl_word; +} +extern "C" { + pub fn _libafl_sync_exit_call1(action: libafl_word, arg1: libafl_word) -> libafl_word; +} +extern "C" { + pub fn _libafl_sync_exit_call2( + action: libafl_word, + arg1: libafl_word, + arg2: libafl_word, + ) -> libafl_word; +} +extern "C" { + pub fn _libafl_backdoor_call0(action: libafl_word) -> libafl_word; +} +extern "C" { + pub fn _libafl_backdoor_call1(action: libafl_word, arg1: libafl_word) -> libafl_word; +} +extern "C" { + pub fn _libafl_backdoor_call2( + action: libafl_word, + arg1: libafl_word, + arg2: libafl_word, + ) -> libafl_word; +} diff --git a/libafl_qemu/src/command.rs b/libafl_qemu/src/command.rs index dbd449f46c..3535b76b52 100644 --- a/libafl_qemu/src/command.rs +++ b/libafl_qemu/src/command.rs @@ -34,7 +34,7 @@ mod bindings { #![allow(clippy::all)] #![allow(clippy::pedantic)] - include!(concat!(env!("OUT_DIR"), "/backdoor_bindings.rs")); + include!(concat!(env!("OUT_DIR"), "/libafl_qemu_bindings.rs")); } #[derive(Debug, Clone, TryFromPrimitive)]