Centralize clippy lints in workspace (#2606)
* centralize clippy definition * fmt * add update bindings script * add a checked and unchecked version of memory read to qemu stuff also, a lot of clippy thing * update binding position * rm old script, new one is a bit better * update doc * macos clippy * adapt fuzzers * windows clippy * fix fuzzer * windows clippy * remove old allowed clippy * remove some allowed clippy * use default features for serde_json in gramatron * better error handler for failed rw to memory
This commit is contained in:
parent
453d733a35
commit
d48a7d508d
40
Cargo.toml
40
Cargo.toml
@ -55,6 +55,7 @@ backtrace = { version = "0.3.74", default-features = false } # Used to get the s
|
|||||||
bindgen = "0.70.1"
|
bindgen = "0.70.1"
|
||||||
clap = "4.5.18"
|
clap = "4.5.18"
|
||||||
cc = "1.1.21"
|
cc = "1.1.21"
|
||||||
|
cmake = "0.1.51"
|
||||||
document-features = "0.2.10"
|
document-features = "0.2.10"
|
||||||
hashbrown = { version = "0.14.5", default-features = false } # A faster hashmap, nostd compatible
|
hashbrown = { version = "0.14.5", default-features = false } # A faster hashmap, nostd compatible
|
||||||
libc = "0.2.159" # For (*nix) libc
|
libc = "0.2.159" # For (*nix) libc
|
||||||
@ -87,6 +88,45 @@ which = "6.0.3"
|
|||||||
windows = "0.58.0"
|
windows = "0.58.0"
|
||||||
z3 = "0.12.1"
|
z3 = "0.12.1"
|
||||||
|
|
||||||
|
|
||||||
|
[workspace.lints.rust]
|
||||||
|
# Forbid
|
||||||
|
unexpected_cfgs = "forbid"
|
||||||
|
|
||||||
|
# Allow
|
||||||
|
incomplete_features = "allow"
|
||||||
|
ambiguous_glob_reexports = "allow"
|
||||||
|
|
||||||
|
|
||||||
|
[workspace.lints.clippy]
|
||||||
|
# Deny
|
||||||
|
all = { level = "deny", priority = -1 }
|
||||||
|
pedantic = { level = "deny", priority = -1 }
|
||||||
|
cargo_common_metadata = "deny"
|
||||||
|
|
||||||
|
# Warn
|
||||||
|
cargo = { level = "warn", priority = -1 }
|
||||||
|
negative_feature_names = "warn"
|
||||||
|
|
||||||
|
# Allow
|
||||||
|
unreadable_literal = "allow"
|
||||||
|
type_repetition_in_bounds = "allow"
|
||||||
|
missing_errors_doc = "allow"
|
||||||
|
cast_possible_truncation = "allow"
|
||||||
|
used_underscore_binding = "allow"
|
||||||
|
ptr_as_ptr = "allow"
|
||||||
|
missing_panics_doc = "allow"
|
||||||
|
module_name_repetitions = "allow"
|
||||||
|
unsafe_derive_deserialize = "allow"
|
||||||
|
similar_names = "allow"
|
||||||
|
too_many_lines = "allow"
|
||||||
|
|
||||||
|
|
||||||
|
[workspace.lints.rustdoc]
|
||||||
|
# Deny
|
||||||
|
broken_intra_doc_links = "deny"
|
||||||
|
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
lto = true
|
lto = true
|
||||||
codegen-units = 1
|
codegen-units = 1
|
||||||
|
@ -159,7 +159,7 @@ impl Client<'_> {
|
|||||||
instance_builder.build().run(
|
instance_builder.build().run(
|
||||||
tuple_list!(
|
tuple_list!(
|
||||||
CmpLogModule::default(),
|
CmpLogModule::default(),
|
||||||
AsanGuestModule::default(qemu, asan_lib.take().unwrap()),
|
AsanGuestModule::default(qemu, &asan_lib.take().unwrap()),
|
||||||
injection_module
|
injection_module
|
||||||
),
|
),
|
||||||
state,
|
state,
|
||||||
@ -168,7 +168,7 @@ impl Client<'_> {
|
|||||||
instance_builder.build().run(
|
instance_builder.build().run(
|
||||||
tuple_list!(
|
tuple_list!(
|
||||||
CmpLogModule::default(),
|
CmpLogModule::default(),
|
||||||
AsanGuestModule::default(qemu, asan_lib.take().unwrap()),
|
AsanGuestModule::default(qemu, &asan_lib.take().unwrap()),
|
||||||
),
|
),
|
||||||
state,
|
state,
|
||||||
)
|
)
|
||||||
@ -186,7 +186,7 @@ impl Client<'_> {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else if is_asan_guest {
|
} else if is_asan_guest {
|
||||||
let modules = tuple_list!(AsanGuestModule::default(qemu, asan_lib.take().unwrap()));
|
let modules = tuple_list!(AsanGuestModule::default(qemu, &asan_lib.take().unwrap()));
|
||||||
instance_builder.build().run(modules, state)
|
instance_builder.build().run(modules, state)
|
||||||
} else if is_cmplog {
|
} else if is_cmplog {
|
||||||
if let Some(injection_module) = injection_module {
|
if let Some(injection_module) = injection_module {
|
||||||
|
@ -98,7 +98,12 @@ impl Harness {
|
|||||||
}
|
}
|
||||||
let len = len as GuestReg;
|
let len = len as GuestReg;
|
||||||
|
|
||||||
unsafe { self.qemu.write_mem(self.input_addr, buf) };
|
self.qemu.write_mem(self.input_addr, buf).map_err(|e| {
|
||||||
|
Error::unknown(format!(
|
||||||
|
"Failed to write to memory@{:#x}: {e:?}",
|
||||||
|
self.input_addr
|
||||||
|
))
|
||||||
|
})?;
|
||||||
|
|
||||||
self.qemu
|
self.qemu
|
||||||
.write_reg(Regs::Pc, self.pc)
|
.write_reg(Regs::Pc, self.pc)
|
||||||
|
@ -273,6 +273,9 @@ document-features = { workspace = true, optional = true }
|
|||||||
# Optional
|
# Optional
|
||||||
clap = { workspace = true, optional = true }
|
clap = { workspace = true, optional = true }
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
[target.'cfg(unix)'.dependencies]
|
[target.'cfg(unix)'.dependencies]
|
||||||
libc = { workspace = true } # For (*nix) libc
|
libc = { workspace = true } # For (*nix) libc
|
||||||
z3 = { workspace = true, optional = true } # for concolic mutation
|
z3 = { workspace = true, optional = true } # for concolic mutation
|
||||||
|
@ -338,7 +338,7 @@ where
|
|||||||
|
|
||||||
/// Launch the broker and the clients and fuzz
|
/// Launch the broker and the clients and fuzz
|
||||||
#[cfg(all(feature = "std", any(windows, not(feature = "fork"))))]
|
#[cfg(all(feature = "std", any(windows, not(feature = "fork"))))]
|
||||||
#[allow(unused_mut, clippy::match_wild_err_arm)]
|
#[allow(unused_mut, clippy::match_wild_err_arm, clippy::too_many_lines)]
|
||||||
pub fn launch_with_hooks<EMH, S>(&mut self, hooks: EMH) -> Result<(), Error>
|
pub fn launch_with_hooks<EMH, S>(&mut self, hooks: EMH) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
S: State + HasExecutions,
|
S: State + HasExecutions,
|
||||||
|
@ -212,8 +212,8 @@ where
|
|||||||
|
|
||||||
impl<A, B, DOT> ProxyObserversTuple<A, B, DOT> {
|
impl<A, B, DOT> ProxyObserversTuple<A, B, DOT> {
|
||||||
fn set(&mut self, primary: &A, secondary: &B) {
|
fn set(&mut self, primary: &A, secondary: &B) {
|
||||||
self.primary = OwnedMutPtr::Ptr(ptr::from_ref(primary) as *mut A);
|
self.primary = OwnedMutPtr::Ptr(ptr::from_ref(primary).cast_mut());
|
||||||
self.secondary = OwnedMutPtr::Ptr(ptr::from_ref(secondary) as *mut B);
|
self.secondary = OwnedMutPtr::Ptr(ptr::from_ref(secondary).cast_mut());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,35 +4,11 @@ Welcome to `LibAFL`
|
|||||||
#![doc = include_str!("../README.md")]
|
#![doc = include_str!("../README.md")]
|
||||||
/*! */
|
/*! */
|
||||||
#![cfg_attr(feature = "document-features", doc = document_features::document_features!())]
|
#![cfg_attr(feature = "document-features", doc = document_features::document_features!())]
|
||||||
#![forbid(unexpected_cfgs)]
|
|
||||||
#![allow(incomplete_features)]
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
// For `type_eq`
|
// For `type_eq`
|
||||||
#![cfg_attr(nightly, feature(specialization))]
|
#![cfg_attr(nightly, feature(specialization))]
|
||||||
// For `std::simd`
|
// For `std::simd`
|
||||||
#![cfg_attr(nightly, feature(portable_simd))]
|
#![cfg_attr(nightly, feature(portable_simd))]
|
||||||
#![warn(clippy::cargo)]
|
|
||||||
#![allow(ambiguous_glob_reexports)]
|
|
||||||
#![deny(clippy::cargo_common_metadata)]
|
|
||||||
#![deny(rustdoc::broken_intra_doc_links)]
|
|
||||||
#![deny(clippy::all)]
|
|
||||||
#![deny(clippy::pedantic)]
|
|
||||||
#![allow(
|
|
||||||
clippy::unreadable_literal,
|
|
||||||
clippy::type_repetition_in_bounds,
|
|
||||||
clippy::missing_errors_doc,
|
|
||||||
clippy::cast_possible_truncation,
|
|
||||||
clippy::used_underscore_binding,
|
|
||||||
clippy::ptr_as_ptr,
|
|
||||||
clippy::missing_panics_doc,
|
|
||||||
clippy::missing_docs_in_private_items,
|
|
||||||
clippy::module_name_repetitions,
|
|
||||||
clippy::ptr_cast_constness,
|
|
||||||
clippy::unsafe_derive_deserialize,
|
|
||||||
clippy::similar_names,
|
|
||||||
clippy::too_many_lines,
|
|
||||||
clippy::into_iter_without_iter, // broken
|
|
||||||
)]
|
|
||||||
#![cfg_attr(not(test), warn(
|
#![cfg_attr(not(test), warn(
|
||||||
missing_debug_implementations,
|
missing_debug_implementations,
|
||||||
missing_docs,
|
missing_docs,
|
||||||
@ -73,9 +49,6 @@ Welcome to `LibAFL`
|
|||||||
while_true
|
while_true
|
||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
// Till they fix this buggy lint in clippy
|
|
||||||
#![allow(clippy::borrow_as_ptr)]
|
|
||||||
#![allow(clippy::borrow_deref_ref)]
|
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
@ -23,6 +23,7 @@ use crate::{
|
|||||||
/// The intent is that the value is something with interior mutability which the target could write to even though this
|
/// The intent is that the value is something with interior mutability which the target could write to even though this
|
||||||
/// observer has a reference to it. Use [`RefCellValueObserver`] if using a [`RefCell`] around the value.
|
/// observer has a reference to it. Use [`RefCellValueObserver`] if using a [`RefCell`] around the value.
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
#[allow(clippy::unsafe_derive_deserialize)]
|
||||||
pub struct ValueObserver<'a, T> {
|
pub struct ValueObserver<'a, T> {
|
||||||
/// The name of this observer.
|
/// The name of this observer.
|
||||||
name: Cow<'static, str>,
|
name: Cow<'static, str>,
|
||||||
@ -82,6 +83,7 @@ impl<T: Hash> ObserverWithHashField for ValueObserver<'_, T> {
|
|||||||
|
|
||||||
/// A simple observer with a single [`RefCell`]'d value.
|
/// A simple observer with a single [`RefCell`]'d value.
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
#[allow(clippy::unsafe_derive_deserialize)]
|
||||||
pub struct RefCellValueObserver<'a, T> {
|
pub struct RefCellValueObserver<'a, T> {
|
||||||
/// The name of this observer.
|
/// The name of this observer.
|
||||||
name: Cow<'static, str>,
|
name: Cow<'static, str>,
|
||||||
|
@ -170,6 +170,9 @@ serial_test = { workspace = true, optional = true, default-features = false, fea
|
|||||||
# Document all features of this crate (for `cargo doc`)
|
# Document all features of this crate (for `cargo doc`)
|
||||||
document-features = { workspace = true, optional = true }
|
document-features = { workspace = true, optional = true }
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
[target.'cfg(unix)'.dependencies]
|
[target.'cfg(unix)'.dependencies]
|
||||||
libc = { workspace = true } # For (*nix) libc
|
libc = { workspace = true } # For (*nix) libc
|
||||||
uds = { version = "0.4.2", optional = true, default-features = false }
|
uds = { version = "0.4.2", optional = true, default-features = false }
|
||||||
|
@ -4,33 +4,11 @@
|
|||||||
#![doc = include_str!("../README.md")]
|
#![doc = include_str!("../README.md")]
|
||||||
/*! */
|
/*! */
|
||||||
#![cfg_attr(feature = "document-features", doc = document_features::document_features!())]
|
#![cfg_attr(feature = "document-features", doc = document_features::document_features!())]
|
||||||
#![forbid(unexpected_cfgs)]
|
|
||||||
#![allow(incomplete_features)]
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
// For `type_eq`
|
// For `type_eq`
|
||||||
#![cfg_attr(nightly, feature(specialization))]
|
#![cfg_attr(nightly, feature(specialization))]
|
||||||
// For `std::simd`
|
// For `std::simd`
|
||||||
#![cfg_attr(nightly, feature(portable_simd))]
|
#![cfg_attr(nightly, feature(portable_simd))]
|
||||||
#![warn(clippy::cargo)]
|
|
||||||
#![allow(ambiguous_glob_reexports)]
|
|
||||||
#![deny(clippy::cargo_common_metadata)]
|
|
||||||
#![deny(rustdoc::broken_intra_doc_links)]
|
|
||||||
#![deny(clippy::all)]
|
|
||||||
#![deny(clippy::pedantic)]
|
|
||||||
#![allow(
|
|
||||||
clippy::unreadable_literal,
|
|
||||||
clippy::type_repetition_in_bounds,
|
|
||||||
clippy::missing_errors_doc,
|
|
||||||
clippy::cast_possible_truncation,
|
|
||||||
clippy::used_underscore_binding,
|
|
||||||
clippy::ptr_as_ptr,
|
|
||||||
clippy::missing_panics_doc,
|
|
||||||
clippy::missing_docs_in_private_items,
|
|
||||||
clippy::module_name_repetitions,
|
|
||||||
clippy::ptr_cast_constness,
|
|
||||||
clippy::negative_feature_names,
|
|
||||||
clippy::too_many_lines
|
|
||||||
)]
|
|
||||||
#![cfg_attr(not(test), warn(
|
#![cfg_attr(not(test), warn(
|
||||||
missing_debug_implementations,
|
missing_debug_implementations,
|
||||||
missing_docs,
|
missing_docs,
|
||||||
@ -71,9 +49,6 @@
|
|||||||
while_true
|
while_true
|
||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
// Till they fix this buggy lint in clippy
|
|
||||||
#![allow(clippy::borrow_as_ptr)]
|
|
||||||
#![allow(clippy::borrow_deref_ref)]
|
|
||||||
|
|
||||||
/// We need some sort of "[`String`]" for errors in `no_alloc`...
|
/// We need some sort of "[`String`]" for errors in `no_alloc`...
|
||||||
/// We can only support `'static` without allocator, so let's do that.
|
/// We can only support `'static` without allocator, so let's do that.
|
||||||
@ -707,7 +682,7 @@ where
|
|||||||
type SliceRef = &'a [T];
|
type SliceRef = &'a [T];
|
||||||
|
|
||||||
fn as_slice(&'a self) -> Self::SliceRef {
|
fn as_slice(&'a self) -> Self::SliceRef {
|
||||||
&*self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2654,6 +2654,7 @@ where
|
|||||||
/// It is supposed that the message is never unmapped.
|
/// It is supposed that the message is never unmapped.
|
||||||
#[inline]
|
#[inline]
|
||||||
#[allow(clippy::cast_ptr_alignment)]
|
#[allow(clippy::cast_ptr_alignment)]
|
||||||
|
#[allow(clippy::too_many_lines)]
|
||||||
unsafe fn handle_new_msgs(&mut self, client_id: ClientId) -> Result<bool, Error> {
|
unsafe fn handle_new_msgs(&mut self, client_id: ClientId) -> Result<bool, Error> {
|
||||||
let mut new_messages = false;
|
let mut new_messages = false;
|
||||||
|
|
||||||
|
@ -1212,7 +1212,7 @@ mod tests {
|
|||||||
proc,
|
proc,
|
||||||
cur,
|
cur,
|
||||||
proc,
|
proc,
|
||||||
&mut out as *mut _,
|
std::ptr::addr_of_mut!(out),
|
||||||
0,
|
0,
|
||||||
true,
|
true,
|
||||||
DUPLICATE_SAME_ACCESS,
|
DUPLICATE_SAME_ACCESS,
|
||||||
@ -1237,7 +1237,7 @@ mod tests {
|
|||||||
} else if cfg!(target_arch = "aarch64") {
|
} else if cfg!(target_arch = "aarch64") {
|
||||||
c.ctx.ContextFlags = CONTEXT_FULL_ARM64;
|
c.ctx.ContextFlags = CONTEXT_FULL_ARM64;
|
||||||
}
|
}
|
||||||
unsafe { GetThreadContext(thread, &mut c.ctx as *mut _).unwrap() };
|
unsafe { GetThreadContext(thread, std::ptr::addr_of_mut!(c.ctx)).unwrap() };
|
||||||
|
|
||||||
let mut writer = BufWriter::new(stdout());
|
let mut writer = BufWriter::new(stdout());
|
||||||
dump_registers(&mut writer, &c.ctx).unwrap();
|
dump_registers(&mut writer, &c.ctx).unwrap();
|
||||||
|
@ -513,7 +513,7 @@ impl<'a, T> From<OwnedMutSlice<'a, T>> for OwnedSlice<'a, T> {
|
|||||||
Self {
|
Self {
|
||||||
inner: match mut_slice.inner {
|
inner: match mut_slice.inner {
|
||||||
OwnedMutSliceInner::RefRaw(ptr, len, unsafe_marker) => {
|
OwnedMutSliceInner::RefRaw(ptr, len, unsafe_marker) => {
|
||||||
OwnedSliceInner::RefRaw(ptr as _, len, unsafe_marker)
|
OwnedSliceInner::RefRaw(ptr.cast_const(), len, unsafe_marker)
|
||||||
}
|
}
|
||||||
OwnedMutSliceInner::Ref(r) => OwnedSliceInner::Ref(r as _),
|
OwnedMutSliceInner::Ref(r) => OwnedSliceInner::Ref(r as _),
|
||||||
OwnedMutSliceInner::Owned(v) => OwnedSliceInner::Owned(v),
|
OwnedMutSliceInner::Owned(v) => OwnedSliceInner::Owned(v),
|
||||||
|
@ -1421,7 +1421,7 @@ pub mod win32_shmem {
|
|||||||
let handle = OpenFileMappingA(
|
let handle = OpenFileMappingA(
|
||||||
FILE_MAP_ALL_ACCESS.0,
|
FILE_MAP_ALL_ACCESS.0,
|
||||||
BOOL(0),
|
BOOL(0),
|
||||||
PCSTR(map_str_bytes.as_ptr() as *mut _),
|
PCSTR(map_str_bytes.as_ptr().cast_mut()),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let map =
|
let map =
|
||||||
|
@ -349,7 +349,7 @@ mod tests {
|
|||||||
|
|
||||||
let bytes_read = bytes_reader.next_sub_slice_truncated(8);
|
let bytes_read = bytes_reader.next_sub_slice_truncated(8);
|
||||||
let bytes_read_ref: &[u8] = &[];
|
let bytes_read_ref: &[u8] = &[];
|
||||||
assert_eq!(&*bytes_read.as_slice(), bytes_read_ref);
|
assert_eq!(bytes_read.as_slice(), bytes_read_ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -55,3 +55,6 @@ serde = { workspace = true, default-features = false, features = [
|
|||||||
"alloc",
|
"alloc",
|
||||||
"derive",
|
"derive",
|
||||||
] } # serialization lib
|
] } # serialization lib
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
@ -1,21 +1,5 @@
|
|||||||
//! Compiler Wrapper from `LibAFL`
|
//! Compiler Wrapper from `LibAFL`
|
||||||
|
|
||||||
#![deny(rustdoc::broken_intra_doc_links)]
|
|
||||||
#![deny(clippy::all)]
|
|
||||||
#![deny(clippy::pedantic)]
|
|
||||||
#![forbid(unexpected_cfgs)]
|
|
||||||
#![allow(
|
|
||||||
clippy::unreadable_literal,
|
|
||||||
clippy::type_repetition_in_bounds,
|
|
||||||
clippy::missing_errors_doc,
|
|
||||||
clippy::cast_possible_truncation,
|
|
||||||
clippy::used_underscore_binding,
|
|
||||||
clippy::ptr_as_ptr,
|
|
||||||
clippy::missing_panics_doc,
|
|
||||||
clippy::missing_docs_in_private_items,
|
|
||||||
clippy::module_name_repetitions,
|
|
||||||
clippy::unreadable_literal
|
|
||||||
)]
|
|
||||||
#![cfg_attr(not(test), warn(
|
#![cfg_attr(not(test), warn(
|
||||||
missing_debug_implementations,
|
missing_debug_implementations,
|
||||||
missing_docs,
|
missing_docs,
|
||||||
|
@ -34,6 +34,9 @@ build = ["which", "cmake"]
|
|||||||
clone = ["which"]
|
clone = ["which"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
which = { version = "6.0.3", optional = true }
|
which = { workspace = true, optional = true }
|
||||||
cmake = { version = "0.1.51", optional = true }
|
cmake = { workspace = true, optional = true }
|
||||||
log = "0.4.22"
|
log = { workspace = true }
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
//! This is a 'meta-package' for libafl that exposes a consistent URL and commit hash for the
|
//! This is a 'meta-package' for libafl that exposes a consistent URL and commit hash for the
|
||||||
//! [`SymCC` fork](https://github.com/AFLplusplus/symcc).
|
//! [`SymCC` fork](https://github.com/AFLplusplus/symcc).
|
||||||
#![allow(clippy::module_name_repetitions)]
|
|
||||||
#![forbid(unexpected_cfgs)]
|
|
||||||
|
|
||||||
/// The URL of the `LibAFL` `SymCC` fork.
|
/// The URL of the `LibAFL` `SymCC` fork.
|
||||||
pub const SYMCC_REPO_URL: &str = "https://github.com/AFLplusplus/symcc.git";
|
pub const SYMCC_REPO_URL: &str = "https://github.com/AFLplusplus/symcc.git";
|
||||||
@ -65,6 +63,8 @@ pub use clone::clone_symcc;
|
|||||||
|
|
||||||
#[cfg(feature = "build")]
|
#[cfg(feature = "build")]
|
||||||
mod build {
|
mod build {
|
||||||
|
#![allow(clippy::module_name_repetitions)]
|
||||||
|
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
/// Builds `SymCC` at the given directory using [`cmake`](https://crates.io/crates/cmake).
|
/// Builds `SymCC` at the given directory using [`cmake`](https://crates.io/crates/cmake).
|
||||||
|
@ -32,9 +32,6 @@ all-features = true
|
|||||||
no-cpp-runtime = []
|
no-cpp-runtime = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
unchecked_unwrap = "4.0.0"
|
|
||||||
ctor = "0.2.8"
|
|
||||||
libc = "0.2.159"
|
|
||||||
libafl = { path = "../../libafl", version = "0.13.2", default-features = false, features = [
|
libafl = { path = "../../libafl", version = "0.13.2", default-features = false, features = [
|
||||||
"std",
|
"std",
|
||||||
"serdeany_autoreg",
|
"serdeany_autoreg",
|
||||||
@ -44,9 +41,16 @@ libafl_bolts = { path = "../../libafl_bolts", version = "0.13.2", default-featur
|
|||||||
"serdeany_autoreg",
|
"serdeany_autoreg",
|
||||||
] }
|
] }
|
||||||
|
|
||||||
|
unchecked_unwrap = "4.0.0"
|
||||||
|
ctor = "0.2.8"
|
||||||
|
libc = { workspace = true }
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
cmake = "0.1.51"
|
cmake = { workspace = true }
|
||||||
bindgen = "0.70.1"
|
bindgen = { workspace = true }
|
||||||
regex = "1.10.6"
|
regex = { workspace = true }
|
||||||
which = "6.0.3"
|
which = { workspace = true }
|
||||||
symcc_libafl = { path = "../symcc_libafl", version = "0.13.2" }
|
symcc_libafl = { path = "../symcc_libafl", version = "0.13.2" }
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
@ -27,12 +27,6 @@
|
|||||||
//! # SymCC and SymQEMU expect to runtime file to be called `libSymRuntime.so`. Setting the name to `SymRuntime` achieves this.
|
//! # SymCC and SymQEMU expect to runtime file to be called `libSymRuntime.so`. Setting the name to `SymRuntime` achieves this.
|
||||||
//! name = "SymRuntime"
|
//! name = "SymRuntime"
|
||||||
//! ```
|
//! ```
|
||||||
#![allow(
|
|
||||||
clippy::module_name_repetitions,
|
|
||||||
clippy::missing_panics_doc,
|
|
||||||
clippy::pub_underscore_fields
|
|
||||||
)]
|
|
||||||
#![forbid(unexpected_cfgs)]
|
|
||||||
|
|
||||||
pub mod filter;
|
pub mod filter;
|
||||||
pub mod tracing;
|
pub mod tracing;
|
||||||
@ -40,8 +34,9 @@ pub mod tracing;
|
|||||||
// The following exports are used by the `export_runtime` macro. They are therefore exported, but hidden from docs, as they are not supposed to be used directly by the user.
|
// The following exports are used by the `export_runtime` macro. They are therefore exported, but hidden from docs, as they are not supposed to be used directly by the user.
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
#[allow(clippy::mixed_attributes_style)]
|
|
||||||
pub mod cpp_runtime {
|
pub mod cpp_runtime {
|
||||||
|
#![allow(clippy::mixed_attributes_style)]
|
||||||
|
#![allow(clippy::pub_underscore_fields)]
|
||||||
#![allow(non_upper_case_globals)]
|
#![allow(non_upper_case_globals)]
|
||||||
#![allow(non_camel_case_types)]
|
#![allow(non_camel_case_types)]
|
||||||
#![allow(non_snake_case)]
|
#![allow(non_snake_case)]
|
||||||
|
@ -22,4 +22,7 @@ categories = [
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
libafl = { path = "../../../libafl" }
|
libafl = { path = "../../../libafl" }
|
||||||
libafl_bolts = { path = "../../../libafl_bolts" }
|
libafl_bolts = { path = "../../../libafl_bolts" }
|
||||||
clap = { version = "4.5.18", features = ["derive"] }
|
clap = { workspace = true, features = ["derive"] }
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
//! This is a straight-forward command line utility that can dump constraints written by a tracing runtime.
|
//! This is a straight-forward command line utility that can dump constraints written by a tracing runtime.
|
||||||
//! It achieves this by running an instrumented target program with the necessary environment variables set.
|
//! It achieves this by running an instrumented target program with the necessary environment variables set.
|
||||||
//! When the program has finished executing, it dumps the traced constraints to a file.
|
//! When the program has finished executing, it dumps the traced constraints to a file.
|
||||||
#![forbid(unexpected_cfgs)]
|
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
ffi::OsString,
|
ffi::OsString,
|
||||||
|
@ -8,7 +8,7 @@ documentation = "https://docs.rs/libafl"
|
|||||||
repository = "https://github.com/AFLplusplus/LibAFL/"
|
repository = "https://github.com/AFLplusplus/LibAFL/"
|
||||||
readme = "../README.md"
|
readme = "../README.md"
|
||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
keywords = ["fuzzing", "libafl", "symbolic", "symcc", "symqemu", "fuzzer"]
|
keywords = ["fuzzing", "libafl", "symbolic", "symcc", "symqemu"]
|
||||||
categories = [
|
categories = [
|
||||||
"development-tools::testing",
|
"development-tools::testing",
|
||||||
"emulators",
|
"emulators",
|
||||||
@ -25,3 +25,6 @@ name = "SymRuntime"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
symcc_runtime = { path = "../../symcc_runtime" }
|
symcc_runtime = { path = "../../symcc_runtime" }
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
@ -24,3 +24,6 @@ proc-macro = true
|
|||||||
syn = { version = "2.0.77", features = ["full", "extra-traits"] }
|
syn = { version = "2.0.77", features = ["full", "extra-traits"] }
|
||||||
quote = "1.0.37"
|
quote = "1.0.37"
|
||||||
proc-macro2 = "1.0.86"
|
proc-macro2 = "1.0.86"
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
@ -1,22 +1,6 @@
|
|||||||
//! Derives for `LibAFL`
|
//! Derives for `LibAFL`
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![forbid(unexpected_cfgs)]
|
|
||||||
#![deny(rustdoc::broken_intra_doc_links)]
|
|
||||||
#![deny(clippy::all)]
|
|
||||||
#![deny(clippy::pedantic)]
|
|
||||||
#![allow(
|
|
||||||
clippy::unreadable_literal,
|
|
||||||
clippy::type_repetition_in_bounds,
|
|
||||||
clippy::missing_errors_doc,
|
|
||||||
clippy::cast_possible_truncation,
|
|
||||||
clippy::used_underscore_binding,
|
|
||||||
clippy::ptr_as_ptr,
|
|
||||||
clippy::missing_panics_doc,
|
|
||||||
clippy::missing_docs_in_private_items,
|
|
||||||
clippy::module_name_repetitions,
|
|
||||||
clippy::unreadable_literal
|
|
||||||
)]
|
|
||||||
#![cfg_attr(not(test), warn(
|
#![cfg_attr(not(test), warn(
|
||||||
missing_debug_implementations,
|
missing_debug_implementations,
|
||||||
missing_docs,
|
missing_docs,
|
||||||
|
@ -46,13 +46,6 @@ auto-download = ["frida-gum-sys/auto-download", "frida-gum/auto-download"]
|
|||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
cc = { workspace = true, features = ["parallel"] }
|
cc = { workspace = true, features = ["parallel"] }
|
||||||
|
|
||||||
[target.'cfg(target_arch = "aarch64")'.dependencies]
|
|
||||||
yaxpeax-arm = "0.3.0"
|
|
||||||
|
|
||||||
[target.'cfg(target_arch = "x86_64")'.dependencies]
|
|
||||||
yaxpeax-x86 = "2.0.0"
|
|
||||||
iced-x86 = { version = "1.21.0", features = ["code_asm"], optional = true }
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
libafl = { path = "../libafl", default-features = false, version = "0.13.2", features = [
|
libafl = { path = "../libafl", default-features = false, version = "0.13.2", features = [
|
||||||
"std",
|
"std",
|
||||||
@ -101,12 +94,6 @@ yaxpeax-arch = "0.3.2"
|
|||||||
|
|
||||||
document-features = { workspace = true, optional = true } # Document all features of this crate (for `cargo doc`)
|
document-features = { workspace = true, optional = true } # Document all features of this crate (for `cargo doc`)
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
|
||||||
winsafe = { version = "0.0.22", features = ["kernel"] }
|
|
||||||
|
|
||||||
[target.'cfg(target_vendor="apple")'.dependencies]
|
|
||||||
mach-sys = { version = "0.5.4" }
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
serial_test = { workspace = true, default-features = false, features = [
|
serial_test = { workspace = true, default-features = false, features = [
|
||||||
"logging",
|
"logging",
|
||||||
@ -115,3 +102,19 @@ clap = { workspace = true, features = ["derive"] }
|
|||||||
libloading = "0.8.5"
|
libloading = "0.8.5"
|
||||||
mimalloc = { workspace = true, default-features = false }
|
mimalloc = { workspace = true, default-features = false }
|
||||||
dlmalloc = { version = "0.2.6", features = ["global"] }
|
dlmalloc = { version = "0.2.6", features = ["global"] }
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
|
[target.'cfg(target_arch = "aarch64")'.dependencies]
|
||||||
|
yaxpeax-arm = "0.3.0"
|
||||||
|
|
||||||
|
[target.'cfg(target_arch = "x86_64")'.dependencies]
|
||||||
|
yaxpeax-x86 = "2.0.0"
|
||||||
|
iced-x86 = { version = "1.21.0", features = ["code_asm"], optional = true }
|
||||||
|
|
||||||
|
[target.'cfg(windows)'.dependencies]
|
||||||
|
winsafe = { version = "0.0.22", features = ["kernel"] }
|
||||||
|
|
||||||
|
[target.'cfg(target_vendor="apple")'.dependencies]
|
||||||
|
mach-sys = { version = "0.5.4" }
|
||||||
|
@ -512,7 +512,7 @@ impl Allocator {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if !self.is_managed(address as *mut c_void) {
|
if !self.is_managed(address.cast_mut()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -605,6 +605,7 @@ impl AsanErrorsObserver {
|
|||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
/// The field should not be accessed multiple times at the same time (i.e., from different threads)!
|
/// The field should not be accessed multiple times at the same time (i.e., from different threads)!
|
||||||
|
#[must_use]
|
||||||
pub fn from_static_asan_errors() -> Self {
|
pub fn from_static_asan_errors() -> Self {
|
||||||
Self::Static
|
Self::Static
|
||||||
}
|
}
|
||||||
|
@ -147,6 +147,7 @@ pub struct FridaInstrumentationHelperBuilder {
|
|||||||
|
|
||||||
impl FridaInstrumentationHelperBuilder {
|
impl FridaInstrumentationHelperBuilder {
|
||||||
/// Create a new [`FridaInstrumentationHelperBuilder`]
|
/// Create a new [`FridaInstrumentationHelperBuilder`]
|
||||||
|
#[must_use]
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self::default()
|
Self::default()
|
||||||
}
|
}
|
||||||
@ -409,6 +410,7 @@ impl FridaInstrumentationHelper<'_, ()> {
|
|||||||
///
|
///
|
||||||
/// See the documentation of [`FridaInstrumentationHelperBuilder`]
|
/// See the documentation of [`FridaInstrumentationHelperBuilder`]
|
||||||
/// for more details.
|
/// for more details.
|
||||||
|
#[must_use]
|
||||||
pub fn builder() -> FridaInstrumentationHelperBuilder {
|
pub fn builder() -> FridaInstrumentationHelperBuilder {
|
||||||
FridaInstrumentationHelperBuilder::default()
|
FridaInstrumentationHelperBuilder::default()
|
||||||
}
|
}
|
||||||
@ -644,6 +646,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns ref to the Transformer
|
/// Returns ref to the Transformer
|
||||||
|
#[must_use]
|
||||||
pub fn transformer(&self) -> &Transformer<'a> {
|
pub fn transformer(&self) -> &Transformer<'a> {
|
||||||
&self.transformer
|
&self.transformer
|
||||||
}
|
}
|
||||||
@ -671,6 +674,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// If stalker is enabled
|
/// If stalker is enabled
|
||||||
|
#[must_use]
|
||||||
pub fn stalker_enabled(&self) -> bool {
|
pub fn stalker_enabled(&self) -> bool {
|
||||||
self.stalker_enabled
|
self.stalker_enabled
|
||||||
}
|
}
|
||||||
@ -684,6 +688,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Ranges
|
/// Ranges
|
||||||
|
#[must_use]
|
||||||
pub fn ranges(&self) -> Ref<RangeMap<usize, (u16, String)>> {
|
pub fn ranges(&self) -> Ref<RangeMap<usize, (u16, String)>> {
|
||||||
self.ranges.borrow()
|
self.ranges.borrow()
|
||||||
}
|
}
|
||||||
|
@ -7,25 +7,6 @@ Additional documentation is available in [the `LibAFL` book](https://aflplus.plu
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
#![cfg_attr(feature = "document-features", doc = document_features::document_features!())]
|
#![cfg_attr(feature = "document-features", doc = document_features::document_features!())]
|
||||||
#![forbid(unexpected_cfgs)]
|
|
||||||
#![deny(rustdoc::broken_intra_doc_links)]
|
|
||||||
#![deny(clippy::all)]
|
|
||||||
#![deny(clippy::pedantic)]
|
|
||||||
#![allow(
|
|
||||||
clippy::unreadable_literal,
|
|
||||||
clippy::type_repetition_in_bounds,
|
|
||||||
clippy::missing_errors_doc,
|
|
||||||
clippy::cast_possible_truncation,
|
|
||||||
clippy::used_underscore_binding,
|
|
||||||
clippy::ptr_as_ptr,
|
|
||||||
clippy::missing_panics_doc,
|
|
||||||
clippy::missing_docs_in_private_items,
|
|
||||||
clippy::module_name_repetitions,
|
|
||||||
clippy::unreadable_literal,
|
|
||||||
clippy::ptr_cast_constness,
|
|
||||||
clippy::must_use_candidate,
|
|
||||||
clippy::too_many_arguments
|
|
||||||
)]
|
|
||||||
#![cfg_attr(not(test), warn(
|
#![cfg_attr(not(test), warn(
|
||||||
missing_debug_implementations,
|
missing_debug_implementations,
|
||||||
missing_docs,
|
missing_docs,
|
||||||
|
@ -162,6 +162,7 @@ const X86_64_REGS: [(RegSpec, X86Register); 34] = [
|
|||||||
|
|
||||||
/// Get the value of a register given a context
|
/// Get the value of a register given a context
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
#[must_use]
|
||||||
pub fn get_register(context: &CpuContext, reg: X86Register) -> u64 {
|
pub fn get_register(context: &CpuContext, reg: X86Register) -> u64 {
|
||||||
match reg {
|
match reg {
|
||||||
X86Register::Rax => context.rax(),
|
X86Register::Rax => context.rax(),
|
||||||
@ -224,8 +225,9 @@ pub(crate) fn frida_to_cs(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
|
||||||
/// Get the `base`, `idx`, `scale`, `disp` for each operand
|
/// Get the `base`, `idx`, `scale`, `disp` for each operand
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
#[must_use]
|
||||||
pub fn operand_details(operand: &Operand) -> Option<(X86Register, X86Register, u8, i32)> {
|
pub fn operand_details(operand: &Operand) -> Option<(X86Register, X86Register, u8, i32)> {
|
||||||
match operand {
|
match operand {
|
||||||
Operand::MemDeref { base } => {
|
Operand::MemDeref { base } => {
|
||||||
@ -263,8 +265,9 @@ pub fn operand_details(operand: &Operand) -> Option<(X86Register, X86Register, u
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
|
||||||
/// Get the immediate value of the operand
|
/// Get the immediate value of the operand
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
#[must_use]
|
||||||
pub fn immediate_value(operand: &Operand) -> Option<i64> {
|
pub fn immediate_value(operand: &Operand) -> Option<i64> {
|
||||||
match operand {
|
match operand {
|
||||||
Operand::ImmediateI8 { imm } => Some(i64::from(*imm)),
|
Operand::ImmediateI8 { imm } => Some(i64::from(*imm)),
|
||||||
@ -290,8 +293,9 @@ pub enum AccessType {
|
|||||||
Write,
|
Write,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
|
||||||
/// Disassemble "count" number of instructions
|
/// Disassemble "count" number of instructions
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
#[must_use]
|
||||||
pub fn disas_count(decoder: &InstDecoder, data: &[u8], count: usize) -> Vec<Instruction> {
|
pub fn disas_count(decoder: &InstDecoder, data: &[u8], count: usize) -> Vec<Instruction> {
|
||||||
let mut counter = count;
|
let mut counter = count;
|
||||||
let mut ret = vec![];
|
let mut ret = vec![];
|
||||||
@ -312,6 +316,7 @@ pub fn disas_count(decoder: &InstDecoder, data: &[u8], count: usize) -> Vec<Inst
|
|||||||
|
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
/// Disassemble "count" number of instructions
|
/// Disassemble "count" number of instructions
|
||||||
|
#[must_use]
|
||||||
pub fn disas_count(decoder: &InstDecoder, data: &[u8], _count: usize) -> Vec<Instruction> {
|
pub fn disas_count(decoder: &InstDecoder, data: &[u8], _count: usize) -> Vec<Instruction> {
|
||||||
let mut ret = vec![];
|
let mut ret = vec![];
|
||||||
|
|
||||||
|
@ -50,3 +50,6 @@ features = ["document-features"]
|
|||||||
all-features = true
|
all-features = true
|
||||||
|
|
||||||
rustdoc-args = ["--cfg", "docsrs"]
|
rustdoc-args = ["--cfg", "docsrs"]
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
@ -75,28 +75,6 @@
|
|||||||
//! to the runtime (e.g., to prevent coverage being collected on the runtime).
|
//! to the runtime (e.g., to prevent coverage being collected on the runtime).
|
||||||
//!
|
//!
|
||||||
#![cfg_attr(feature = "document-features", doc = document_features::document_features!())]
|
#![cfg_attr(feature = "document-features", doc = document_features::document_features!())]
|
||||||
#![forbid(unexpected_cfgs)]
|
|
||||||
#![warn(clippy::cargo)]
|
|
||||||
#![allow(ambiguous_glob_reexports)]
|
|
||||||
#![deny(clippy::cargo_common_metadata)]
|
|
||||||
#![deny(rustdoc::broken_intra_doc_links)]
|
|
||||||
#![deny(clippy::all)]
|
|
||||||
#![deny(clippy::pedantic)]
|
|
||||||
#![allow(
|
|
||||||
clippy::unreadable_literal,
|
|
||||||
clippy::type_repetition_in_bounds,
|
|
||||||
clippy::missing_errors_doc,
|
|
||||||
clippy::cast_possible_truncation,
|
|
||||||
clippy::used_underscore_binding,
|
|
||||||
clippy::ptr_as_ptr,
|
|
||||||
clippy::missing_panics_doc,
|
|
||||||
clippy::missing_docs_in_private_items,
|
|
||||||
clippy::module_name_repetitions,
|
|
||||||
clippy::ptr_cast_constness,
|
|
||||||
clippy::unsafe_derive_deserialize,
|
|
||||||
clippy::similar_names,
|
|
||||||
clippy::too_many_lines
|
|
||||||
)]
|
|
||||||
#![cfg_attr(not(test), warn(
|
#![cfg_attr(not(test), warn(
|
||||||
missing_debug_implementations,
|
missing_debug_implementations,
|
||||||
missing_docs,
|
missing_docs,
|
||||||
@ -137,9 +115,6 @@
|
|||||||
while_true
|
while_true
|
||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
// Till they fix this buggy lint in clippy
|
|
||||||
#![allow(clippy::borrow_as_ptr)]
|
|
||||||
#![allow(clippy::borrow_deref_ref)]
|
|
||||||
|
|
||||||
use std::ffi::{c_char, c_int};
|
use std::ffi::{c_char, c_int};
|
||||||
|
|
||||||
|
@ -38,3 +38,6 @@ libafl_targets = { path = "../libafl_targets", version = "0.13.2", features = [
|
|||||||
|
|
||||||
nix = { workspace = true, default-features = true, features = ["fs"] }
|
nix = { workspace = true, default-features = true, features = ["fs"] }
|
||||||
typed-builder = { workspace = true }
|
typed-builder = { workspace = true }
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
@ -1,6 +1,3 @@
|
|||||||
#![allow(clippy::module_name_repetitions, clippy::missing_panics_doc)]
|
|
||||||
#![forbid(unexpected_cfgs)]
|
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
pub mod executor;
|
pub mod executor;
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
|
@ -142,3 +142,6 @@ cc = { workspace = true }
|
|||||||
[lib]
|
[lib]
|
||||||
name = "libafl_qemu"
|
name = "libafl_qemu"
|
||||||
crate-type = ["cdylib", "rlib"]
|
crate-type = ["cdylib", "rlib"]
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
@ -39,3 +39,6 @@ cc = { workspace = true }
|
|||||||
regex = { workspace = true }
|
regex = { workspace = true }
|
||||||
rustversion = { workspace = true }
|
rustversion = { workspace = true }
|
||||||
rustc_version = "0.4.1"
|
rustc_version = "0.4.1"
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
@ -1,6 +1,3 @@
|
|||||||
#![forbid(unexpected_cfgs)]
|
|
||||||
#![allow(clippy::missing_panics_doc)]
|
|
||||||
|
|
||||||
// #[rustversion::nightly]
|
// #[rustversion::nightly]
|
||||||
// use std::io::{BufRead, BufReader};
|
// use std::io::{BufRead, BufReader};
|
||||||
use std::{
|
use std::{
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
#![forbid(unexpected_cfgs)]
|
|
||||||
|
|
||||||
use std::path::PathBuf;
|
|
||||||
|
|
||||||
use libafl_qemu_build::build_with_bindings;
|
|
||||||
|
|
||||||
// RUST_BACKTRACE=1 OUT_DIR=/tmp/foo/a/b/c cargo run
|
|
||||||
fn main() {
|
|
||||||
let bfile = PathBuf::from("generated_qemu_bindings.rs");
|
|
||||||
build_with_bindings("arm", false, false, None, &bfile);
|
|
||||||
}
|
|
@ -65,3 +65,6 @@ pyo3 = { workspace = true, optional = true }
|
|||||||
libafl_qemu_build = { path = "../libafl_qemu_build", version = "0.13.2" }
|
libafl_qemu_build = { path = "../libafl_qemu_build", version = "0.13.2" }
|
||||||
pyo3-build-config = { workspace = true, optional = true }
|
pyo3-build-config = { workspace = true, optional = true }
|
||||||
rustversion = { workspace = true }
|
rustversion = { workspace = true }
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
@ -65,6 +65,7 @@ pub fn build() {
|
|||||||
})
|
})
|
||||||
};
|
};
|
||||||
println!("cargo:rerun-if-env-changed=CPU_TARGET");
|
println!("cargo:rerun-if-env-changed=CPU_TARGET");
|
||||||
|
println!("cargo:rerun-if-env-changed=LIBAFL_QEMU_GEN_STUBS");
|
||||||
println!("cargo:rustc-cfg=cpu_target=\"{cpu_target}\"");
|
println!("cargo:rustc-cfg=cpu_target=\"{cpu_target}\"");
|
||||||
println!("cargo::rustc-check-cfg=cfg(cpu_target, values(\"x86_64\", \"arm\", \"aarch64\", \"i386\", \"mips\", \"ppc\", \"hexagon\"))");
|
println!("cargo::rustc-check-cfg=cfg(cpu_target, values(\"x86_64\", \"arm\", \"aarch64\", \"i386\", \"mips\", \"ppc\", \"hexagon\"))");
|
||||||
|
|
||||||
@ -78,7 +79,7 @@ pub fn build() {
|
|||||||
|
|
||||||
let src_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
|
let src_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
|
||||||
let src_dir = PathBuf::from(src_dir);
|
let src_dir = PathBuf::from(src_dir);
|
||||||
let stub_bindings_file = src_dir.join("src/x86_64_stub_bindings.rs");
|
let stub_bindings_file = src_dir.join("src/bindings/x86_64_stub_bindings.rs");
|
||||||
|
|
||||||
if env::var("DOCS_RS").is_ok() || cfg!(feature = "clippy") {
|
if env::var("DOCS_RS").is_ok() || cfg!(feature = "clippy") {
|
||||||
// Only build when we're not generating docs and not in clippy
|
// Only build when we're not generating docs and not in clippy
|
||||||
|
18
libafl_qemu/libafl_qemu_sys/src/bindings/mod.rs
Normal file
18
libafl_qemu/libafl_qemu_sys/src/bindings/mod.rs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#![allow(non_upper_case_globals)]
|
||||||
|
#![allow(non_camel_case_types)]
|
||||||
|
#![allow(non_snake_case)]
|
||||||
|
#![allow(unused_mut)]
|
||||||
|
#![allow(unused)]
|
||||||
|
#![allow(unused_variables)]
|
||||||
|
#![allow(clippy::all)]
|
||||||
|
#![allow(clippy::pedantic)]
|
||||||
|
#![allow(improper_ctypes)]
|
||||||
|
|
||||||
|
#[cfg(all(not(feature = "clippy"), target_os = "linux"))]
|
||||||
|
#[rustfmt::skip]
|
||||||
|
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
|
||||||
|
|
||||||
|
#[cfg(any(feature = "clippy", not(target_os = "linux")))]
|
||||||
|
mod x86_64_stub_bindings;
|
||||||
|
#[cfg(any(feature = "clippy", not(target_os = "linux")))]
|
||||||
|
pub use x86_64_stub_bindings::*;
|
7004
libafl_qemu/libafl_qemu_sys/src/bindings/x86_64_stub_bindings.rs
Normal file
7004
libafl_qemu/libafl_qemu_sys/src/bindings/x86_64_stub_bindings.rs
Normal file
File diff suppressed because it is too large
Load Diff
@ -5,14 +5,6 @@ Have a look at `libafl_qemu` for higher-level abstractions.
|
|||||||
__Warning__: The documentation is built by default for `x86_64` in `usermode`. To access the documentation of other architectures or systemmode, the documentation must be rebuilt with the right features.
|
__Warning__: The documentation is built by default for `x86_64` in `usermode`. To access the documentation of other architectures or systemmode, the documentation must be rebuilt with the right features.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#![forbid(unexpected_cfgs)]
|
|
||||||
#![allow(non_upper_case_globals)]
|
|
||||||
#![allow(non_camel_case_types)]
|
|
||||||
#![allow(non_snake_case)]
|
|
||||||
#![allow(improper_ctypes)]
|
|
||||||
#![allow(unused_mut)]
|
|
||||||
#![allow(clippy::all)]
|
|
||||||
#![allow(clippy::pedantic)]
|
|
||||||
#![cfg_attr(nightly, feature(used_with_arg))]
|
#![cfg_attr(nightly, feature(used_with_arg))]
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
@ -22,30 +14,9 @@ use std::ffi::c_void;
|
|||||||
use num_enum::{IntoPrimitive, TryFromPrimitive};
|
use num_enum::{IntoPrimitive, TryFromPrimitive};
|
||||||
use strum_macros::EnumIter;
|
use strum_macros::EnumIter;
|
||||||
|
|
||||||
#[cfg(all(not(feature = "clippy"), target_os = "linux"))]
|
mod bindings;
|
||||||
mod bindings {
|
|
||||||
#![allow(non_upper_case_globals)]
|
|
||||||
#![allow(non_camel_case_types)]
|
|
||||||
#![allow(non_snake_case)]
|
|
||||||
#![allow(improper_ctypes)]
|
|
||||||
#![allow(unused_mut)]
|
|
||||||
#![allow(unused)]
|
|
||||||
#![allow(unused_variables)]
|
|
||||||
#![allow(clippy::all)]
|
|
||||||
#![allow(clippy::pedantic)]
|
|
||||||
|
|
||||||
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
|
|
||||||
}
|
|
||||||
#[cfg(all(not(feature = "clippy"), target_os = "linux"))]
|
|
||||||
pub use bindings::*;
|
pub use bindings::*;
|
||||||
|
|
||||||
#[cfg(any(feature = "clippy", not(target_os = "linux")))]
|
|
||||||
#[allow(dead_code)]
|
|
||||||
#[rustfmt::skip]
|
|
||||||
mod x86_64_stub_bindings;
|
|
||||||
#[cfg(any(feature = "clippy", not(target_os = "linux")))]
|
|
||||||
pub use x86_64_stub_bindings::*;
|
|
||||||
|
|
||||||
#[cfg(emulation_mode = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
mod usermode;
|
mod usermode;
|
||||||
#[cfg(emulation_mode = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
@ -57,6 +28,7 @@ pub use usermode::*;
|
|||||||
// pub use systemmode::*;
|
// pub use systemmode::*;
|
||||||
|
|
||||||
/// Safe linking with of extern "C" functions.
|
/// Safe linking with of extern "C" functions.
|
||||||
|
///
|
||||||
/// This macro makes sure the declared symbol is defined *at link time*, avoiding declaring non-existant symbols
|
/// This macro makes sure the declared symbol is defined *at link time*, avoiding declaring non-existant symbols
|
||||||
/// that could be silently ignored during linking if unused.
|
/// that could be silently ignored during linking if unused.
|
||||||
///
|
///
|
||||||
@ -153,11 +125,13 @@ pub enum MmapPerms {
|
|||||||
// from include/exec/memop.h
|
// from include/exec/memop.h
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
|
#[must_use]
|
||||||
pub fn memop_size(op: MemOp) -> u32 {
|
pub fn memop_size(op: MemOp) -> u32 {
|
||||||
1 << op.bitand(MemOp_MO_SIZE).0
|
1 << op.bitand(MemOp_MO_SIZE).0
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
|
#[must_use]
|
||||||
pub fn memop_big_endian(op: MemOp) -> bool {
|
pub fn memop_big_endian(op: MemOp) -> bool {
|
||||||
op.bitand(MemOp_MO_BSWAP) == MemOp_MO_BE
|
op.bitand(MemOp_MO_BSWAP) == MemOp_MO_BE
|
||||||
}
|
}
|
||||||
@ -165,6 +139,7 @@ pub fn memop_big_endian(op: MemOp) -> bool {
|
|||||||
// from include/qemu/plugin.h
|
// from include/qemu/plugin.h
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
|
#[must_use]
|
||||||
pub fn make_plugin_meminfo(oi: MemOpIdx, rw: qemu_plugin_mem_rw) -> qemu_plugin_meminfo_t {
|
pub fn make_plugin_meminfo(oi: MemOpIdx, rw: qemu_plugin_mem_rw) -> qemu_plugin_meminfo_t {
|
||||||
oi | (rw.0 << 16)
|
oi | (rw.0 << 16)
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,10 +1,10 @@
|
|||||||
/* 1.83.0-nightly */
|
/* 1.83.0-nightly */
|
||||||
/* qemu git hash: d6637939526f453c69f4c6bfe4635feb5dc5c0be */
|
/* qemu git hash: d6637939526f453c69f4c6bfe4635feb5dc5c0be */
|
||||||
/* automatically generated by rust-bindgen 0.69.4 */
|
/* automatically generated by rust-bindgen 0.70.1 */
|
||||||
|
|
||||||
pub const LIBAFL_SYNC_EXIT_OPCODE: u32 = 1727150607;
|
pub const LIBAFL_SYNC_EXIT_OPCODE: u32 = 1727150607;
|
||||||
pub const LIBAFL_BACKDOOR_OPCODE: u32 = 1156725263;
|
pub const LIBAFL_BACKDOOR_OPCODE: u32 = 1156725263;
|
||||||
pub const LIBAFL_QEMU_TEST_VALUE: i64 = -2401053089206453570;
|
pub const LIBAFL_QEMU_TEST_VALUE: u32 = 3405691582;
|
||||||
pub const LIBAFL_QEMU_HDR_VERSION_NUMBER: u32 = 73;
|
pub const LIBAFL_QEMU_HDR_VERSION_NUMBER: u32 = 73;
|
||||||
pub const _STDIO_H: u32 = 1;
|
pub const _STDIO_H: u32 = 1;
|
||||||
pub const _FEATURES_H: u32 = 1;
|
pub const _FEATURES_H: u32 = 1;
|
||||||
@ -235,31 +235,12 @@ pub type __pid_t = ::std::os::raw::c_int;
|
|||||||
pub struct __fsid_t {
|
pub struct __fsid_t {
|
||||||
pub __val: [::std::os::raw::c_int; 2usize],
|
pub __val: [::std::os::raw::c_int; 2usize],
|
||||||
}
|
}
|
||||||
#[test]
|
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
|
||||||
fn bindgen_test_layout___fsid_t() {
|
const _: () = {
|
||||||
const UNINIT: ::std::mem::MaybeUninit<__fsid_t> = ::std::mem::MaybeUninit::uninit();
|
["Size of __fsid_t"][::std::mem::size_of::<__fsid_t>() - 8usize];
|
||||||
let ptr = UNINIT.as_ptr();
|
["Alignment of __fsid_t"][::std::mem::align_of::<__fsid_t>() - 4usize];
|
||||||
assert_eq!(
|
["Offset of field: __fsid_t::__val"][::std::mem::offset_of!(__fsid_t, __val) - 0usize];
|
||||||
::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 __clock_t = ::std::os::raw::c_long;
|
||||||
pub type __rlim_t = ::std::os::raw::c_ulong;
|
pub type __rlim_t = ::std::os::raw::c_ulong;
|
||||||
pub type __rlim64_t = ::std::os::raw::c_ulong;
|
pub type __rlim64_t = ::std::os::raw::c_ulong;
|
||||||
@ -300,42 +281,17 @@ pub union __mbstate_t__bindgen_ty_1 {
|
|||||||
pub __wch: ::std::os::raw::c_uint,
|
pub __wch: ::std::os::raw::c_uint,
|
||||||
pub __wchb: [::std::os::raw::c_char; 4usize],
|
pub __wchb: [::std::os::raw::c_char; 4usize],
|
||||||
}
|
}
|
||||||
#[test]
|
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
|
||||||
fn bindgen_test_layout___mbstate_t__bindgen_ty_1() {
|
const _: () = {
|
||||||
const UNINIT: ::std::mem::MaybeUninit<__mbstate_t__bindgen_ty_1> =
|
["Size of __mbstate_t__bindgen_ty_1"]
|
||||||
::std::mem::MaybeUninit::uninit();
|
[::std::mem::size_of::<__mbstate_t__bindgen_ty_1>() - 4usize];
|
||||||
let ptr = UNINIT.as_ptr();
|
["Alignment of __mbstate_t__bindgen_ty_1"]
|
||||||
assert_eq!(
|
[::std::mem::align_of::<__mbstate_t__bindgen_ty_1>() - 4usize];
|
||||||
::std::mem::size_of::<__mbstate_t__bindgen_ty_1>(),
|
["Offset of field: __mbstate_t__bindgen_ty_1::__wch"]
|
||||||
4usize,
|
[::std::mem::offset_of!(__mbstate_t__bindgen_ty_1, __wch) - 0usize];
|
||||||
concat!("Size of: ", stringify!(__mbstate_t__bindgen_ty_1))
|
["Offset of field: __mbstate_t__bindgen_ty_1::__wchb"]
|
||||||
);
|
[::std::mem::offset_of!(__mbstate_t__bindgen_ty_1, __wchb) - 0usize];
|
||||||
assert_eq!(
|
};
|
||||||
::std::mem::align_of::<__mbstate_t__bindgen_ty_1>(),
|
|
||||||
4usize,
|
|
||||||
concat!("Alignment of ", stringify!(__mbstate_t__bindgen_ty_1))
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
unsafe { ::std::ptr::addr_of!((*ptr).__wch) as usize - ptr as usize },
|
|
||||||
0usize,
|
|
||||||
concat!(
|
|
||||||
"Offset of field: ",
|
|
||||||
stringify!(__mbstate_t__bindgen_ty_1),
|
|
||||||
"::",
|
|
||||||
stringify!(__wch)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
unsafe { ::std::ptr::addr_of!((*ptr).__wchb) as usize - ptr as usize },
|
|
||||||
0usize,
|
|
||||||
concat!(
|
|
||||||
"Offset of field: ",
|
|
||||||
stringify!(__mbstate_t__bindgen_ty_1),
|
|
||||||
"::",
|
|
||||||
stringify!(__wchb)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
impl Default for __mbstate_t__bindgen_ty_1 {
|
impl Default for __mbstate_t__bindgen_ty_1 {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
|
let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
|
||||||
@ -350,41 +306,15 @@ impl ::std::fmt::Debug for __mbstate_t__bindgen_ty_1 {
|
|||||||
write!(f, "__mbstate_t__bindgen_ty_1 {{ union }}")
|
write!(f, "__mbstate_t__bindgen_ty_1 {{ union }}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[test]
|
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
|
||||||
fn bindgen_test_layout___mbstate_t() {
|
const _: () = {
|
||||||
const UNINIT: ::std::mem::MaybeUninit<__mbstate_t> = ::std::mem::MaybeUninit::uninit();
|
["Size of __mbstate_t"][::std::mem::size_of::<__mbstate_t>() - 8usize];
|
||||||
let ptr = UNINIT.as_ptr();
|
["Alignment of __mbstate_t"][::std::mem::align_of::<__mbstate_t>() - 4usize];
|
||||||
assert_eq!(
|
["Offset of field: __mbstate_t::__count"]
|
||||||
::std::mem::size_of::<__mbstate_t>(),
|
[::std::mem::offset_of!(__mbstate_t, __count) - 0usize];
|
||||||
8usize,
|
["Offset of field: __mbstate_t::__value"]
|
||||||
concat!("Size of: ", stringify!(__mbstate_t))
|
[::std::mem::offset_of!(__mbstate_t, __value) - 4usize];
|
||||||
);
|
};
|
||||||
assert_eq!(
|
|
||||||
::std::mem::align_of::<__mbstate_t>(),
|
|
||||||
4usize,
|
|
||||||
concat!("Alignment of ", stringify!(__mbstate_t))
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
unsafe { ::std::ptr::addr_of!((*ptr).__count) as usize - ptr as usize },
|
|
||||||
0usize,
|
|
||||||
concat!(
|
|
||||||
"Offset of field: ",
|
|
||||||
stringify!(__mbstate_t),
|
|
||||||
"::",
|
|
||||||
stringify!(__count)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
unsafe { ::std::ptr::addr_of!((*ptr).__value) as usize - ptr as usize },
|
|
||||||
4usize,
|
|
||||||
concat!(
|
|
||||||
"Offset of field: ",
|
|
||||||
stringify!(__mbstate_t),
|
|
||||||
"::",
|
|
||||||
stringify!(__value)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
impl Default for __mbstate_t {
|
impl Default for __mbstate_t {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
|
let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
|
||||||
@ -409,41 +339,13 @@ pub struct _G_fpos_t {
|
|||||||
pub __pos: __off_t,
|
pub __pos: __off_t,
|
||||||
pub __state: __mbstate_t,
|
pub __state: __mbstate_t,
|
||||||
}
|
}
|
||||||
#[test]
|
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
|
||||||
fn bindgen_test_layout__G_fpos_t() {
|
const _: () = {
|
||||||
const UNINIT: ::std::mem::MaybeUninit<_G_fpos_t> = ::std::mem::MaybeUninit::uninit();
|
["Size of _G_fpos_t"][::std::mem::size_of::<_G_fpos_t>() - 16usize];
|
||||||
let ptr = UNINIT.as_ptr();
|
["Alignment of _G_fpos_t"][::std::mem::align_of::<_G_fpos_t>() - 8usize];
|
||||||
assert_eq!(
|
["Offset of field: _G_fpos_t::__pos"][::std::mem::offset_of!(_G_fpos_t, __pos) - 0usize];
|
||||||
::std::mem::size_of::<_G_fpos_t>(),
|
["Offset of field: _G_fpos_t::__state"][::std::mem::offset_of!(_G_fpos_t, __state) - 8usize];
|
||||||
16usize,
|
};
|
||||||
concat!("Size of: ", stringify!(_G_fpos_t))
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
::std::mem::align_of::<_G_fpos_t>(),
|
|
||||||
8usize,
|
|
||||||
concat!("Alignment of ", stringify!(_G_fpos_t))
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
unsafe { ::std::ptr::addr_of!((*ptr).__pos) as usize - ptr as usize },
|
|
||||||
0usize,
|
|
||||||
concat!(
|
|
||||||
"Offset of field: ",
|
|
||||||
stringify!(_G_fpos_t),
|
|
||||||
"::",
|
|
||||||
stringify!(__pos)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
unsafe { ::std::ptr::addr_of!((*ptr).__state) as usize - ptr as usize },
|
|
||||||
8usize,
|
|
||||||
concat!(
|
|
||||||
"Offset of field: ",
|
|
||||||
stringify!(_G_fpos_t),
|
|
||||||
"::",
|
|
||||||
stringify!(__state)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
impl Default for _G_fpos_t {
|
impl Default for _G_fpos_t {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
|
let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
|
||||||
@ -469,41 +371,14 @@ pub struct _G_fpos64_t {
|
|||||||
pub __pos: __off64_t,
|
pub __pos: __off64_t,
|
||||||
pub __state: __mbstate_t,
|
pub __state: __mbstate_t,
|
||||||
}
|
}
|
||||||
#[test]
|
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
|
||||||
fn bindgen_test_layout__G_fpos64_t() {
|
const _: () = {
|
||||||
const UNINIT: ::std::mem::MaybeUninit<_G_fpos64_t> = ::std::mem::MaybeUninit::uninit();
|
["Size of _G_fpos64_t"][::std::mem::size_of::<_G_fpos64_t>() - 16usize];
|
||||||
let ptr = UNINIT.as_ptr();
|
["Alignment of _G_fpos64_t"][::std::mem::align_of::<_G_fpos64_t>() - 8usize];
|
||||||
assert_eq!(
|
["Offset of field: _G_fpos64_t::__pos"][::std::mem::offset_of!(_G_fpos64_t, __pos) - 0usize];
|
||||||
::std::mem::size_of::<_G_fpos64_t>(),
|
["Offset of field: _G_fpos64_t::__state"]
|
||||||
16usize,
|
[::std::mem::offset_of!(_G_fpos64_t, __state) - 8usize];
|
||||||
concat!("Size of: ", stringify!(_G_fpos64_t))
|
};
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
::std::mem::align_of::<_G_fpos64_t>(),
|
|
||||||
8usize,
|
|
||||||
concat!("Alignment of ", stringify!(_G_fpos64_t))
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
unsafe { ::std::ptr::addr_of!((*ptr).__pos) as usize - ptr as usize },
|
|
||||||
0usize,
|
|
||||||
concat!(
|
|
||||||
"Offset of field: ",
|
|
||||||
stringify!(_G_fpos64_t),
|
|
||||||
"::",
|
|
||||||
stringify!(__pos)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
unsafe { ::std::ptr::addr_of!((*ptr).__state) as usize - ptr as usize },
|
|
||||||
8usize,
|
|
||||||
concat!(
|
|
||||||
"Offset of field: ",
|
|
||||||
stringify!(_G_fpos64_t),
|
|
||||||
"::",
|
|
||||||
stringify!(__state)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
impl Default for _G_fpos64_t {
|
impl Default for _G_fpos64_t {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
|
let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
|
||||||
@ -574,311 +449,59 @@ pub struct _IO_FILE {
|
|||||||
pub _mode: ::std::os::raw::c_int,
|
pub _mode: ::std::os::raw::c_int,
|
||||||
pub _unused2: [::std::os::raw::c_char; 20usize],
|
pub _unused2: [::std::os::raw::c_char; 20usize],
|
||||||
}
|
}
|
||||||
#[test]
|
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
|
||||||
fn bindgen_test_layout__IO_FILE() {
|
const _: () = {
|
||||||
const UNINIT: ::std::mem::MaybeUninit<_IO_FILE> = ::std::mem::MaybeUninit::uninit();
|
["Size of _IO_FILE"][::std::mem::size_of::<_IO_FILE>() - 216usize];
|
||||||
let ptr = UNINIT.as_ptr();
|
["Alignment of _IO_FILE"][::std::mem::align_of::<_IO_FILE>() - 8usize];
|
||||||
assert_eq!(
|
["Offset of field: _IO_FILE::_flags"][::std::mem::offset_of!(_IO_FILE, _flags) - 0usize];
|
||||||
::std::mem::size_of::<_IO_FILE>(),
|
["Offset of field: _IO_FILE::_IO_read_ptr"]
|
||||||
216usize,
|
[::std::mem::offset_of!(_IO_FILE, _IO_read_ptr) - 8usize];
|
||||||
concat!("Size of: ", stringify!(_IO_FILE))
|
["Offset of field: _IO_FILE::_IO_read_end"]
|
||||||
);
|
[::std::mem::offset_of!(_IO_FILE, _IO_read_end) - 16usize];
|
||||||
assert_eq!(
|
["Offset of field: _IO_FILE::_IO_read_base"]
|
||||||
::std::mem::align_of::<_IO_FILE>(),
|
[::std::mem::offset_of!(_IO_FILE, _IO_read_base) - 24usize];
|
||||||
8usize,
|
["Offset of field: _IO_FILE::_IO_write_base"]
|
||||||
concat!("Alignment of ", stringify!(_IO_FILE))
|
[::std::mem::offset_of!(_IO_FILE, _IO_write_base) - 32usize];
|
||||||
);
|
["Offset of field: _IO_FILE::_IO_write_ptr"]
|
||||||
assert_eq!(
|
[::std::mem::offset_of!(_IO_FILE, _IO_write_ptr) - 40usize];
|
||||||
unsafe { ::std::ptr::addr_of!((*ptr)._flags) as usize - ptr as usize },
|
["Offset of field: _IO_FILE::_IO_write_end"]
|
||||||
0usize,
|
[::std::mem::offset_of!(_IO_FILE, _IO_write_end) - 48usize];
|
||||||
concat!(
|
["Offset of field: _IO_FILE::_IO_buf_base"]
|
||||||
"Offset of field: ",
|
[::std::mem::offset_of!(_IO_FILE, _IO_buf_base) - 56usize];
|
||||||
stringify!(_IO_FILE),
|
["Offset of field: _IO_FILE::_IO_buf_end"]
|
||||||
"::",
|
[::std::mem::offset_of!(_IO_FILE, _IO_buf_end) - 64usize];
|
||||||
stringify!(_flags)
|
["Offset of field: _IO_FILE::_IO_save_base"]
|
||||||
)
|
[::std::mem::offset_of!(_IO_FILE, _IO_save_base) - 72usize];
|
||||||
);
|
["Offset of field: _IO_FILE::_IO_backup_base"]
|
||||||
assert_eq!(
|
[::std::mem::offset_of!(_IO_FILE, _IO_backup_base) - 80usize];
|
||||||
unsafe { ::std::ptr::addr_of!((*ptr)._IO_read_ptr) as usize - ptr as usize },
|
["Offset of field: _IO_FILE::_IO_save_end"]
|
||||||
8usize,
|
[::std::mem::offset_of!(_IO_FILE, _IO_save_end) - 88usize];
|
||||||
concat!(
|
["Offset of field: _IO_FILE::_markers"][::std::mem::offset_of!(_IO_FILE, _markers) - 96usize];
|
||||||
"Offset of field: ",
|
["Offset of field: _IO_FILE::_chain"][::std::mem::offset_of!(_IO_FILE, _chain) - 104usize];
|
||||||
stringify!(_IO_FILE),
|
["Offset of field: _IO_FILE::_fileno"][::std::mem::offset_of!(_IO_FILE, _fileno) - 112usize];
|
||||||
"::",
|
["Offset of field: _IO_FILE::_flags2"][::std::mem::offset_of!(_IO_FILE, _flags2) - 116usize];
|
||||||
stringify!(_IO_read_ptr)
|
["Offset of field: _IO_FILE::_old_offset"]
|
||||||
)
|
[::std::mem::offset_of!(_IO_FILE, _old_offset) - 120usize];
|
||||||
);
|
["Offset of field: _IO_FILE::_cur_column"]
|
||||||
assert_eq!(
|
[::std::mem::offset_of!(_IO_FILE, _cur_column) - 128usize];
|
||||||
unsafe { ::std::ptr::addr_of!((*ptr)._IO_read_end) as usize - ptr as usize },
|
["Offset of field: _IO_FILE::_vtable_offset"]
|
||||||
16usize,
|
[::std::mem::offset_of!(_IO_FILE, _vtable_offset) - 130usize];
|
||||||
concat!(
|
["Offset of field: _IO_FILE::_shortbuf"]
|
||||||
"Offset of field: ",
|
[::std::mem::offset_of!(_IO_FILE, _shortbuf) - 131usize];
|
||||||
stringify!(_IO_FILE),
|
["Offset of field: _IO_FILE::_lock"][::std::mem::offset_of!(_IO_FILE, _lock) - 136usize];
|
||||||
"::",
|
["Offset of field: _IO_FILE::_offset"][::std::mem::offset_of!(_IO_FILE, _offset) - 144usize];
|
||||||
stringify!(_IO_read_end)
|
["Offset of field: _IO_FILE::_codecvt"][::std::mem::offset_of!(_IO_FILE, _codecvt) - 152usize];
|
||||||
)
|
["Offset of field: _IO_FILE::_wide_data"]
|
||||||
);
|
[::std::mem::offset_of!(_IO_FILE, _wide_data) - 160usize];
|
||||||
assert_eq!(
|
["Offset of field: _IO_FILE::_freeres_list"]
|
||||||
unsafe { ::std::ptr::addr_of!((*ptr)._IO_read_base) as usize - ptr as usize },
|
[::std::mem::offset_of!(_IO_FILE, _freeres_list) - 168usize];
|
||||||
24usize,
|
["Offset of field: _IO_FILE::_freeres_buf"]
|
||||||
concat!(
|
[::std::mem::offset_of!(_IO_FILE, _freeres_buf) - 176usize];
|
||||||
"Offset of field: ",
|
["Offset of field: _IO_FILE::_prevchain"]
|
||||||
stringify!(_IO_FILE),
|
[::std::mem::offset_of!(_IO_FILE, _prevchain) - 184usize];
|
||||||
"::",
|
["Offset of field: _IO_FILE::_mode"][::std::mem::offset_of!(_IO_FILE, _mode) - 192usize];
|
||||||
stringify!(_IO_read_base)
|
["Offset of field: _IO_FILE::_unused2"][::std::mem::offset_of!(_IO_FILE, _unused2) - 196usize];
|
||||||
)
|
};
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
unsafe { ::std::ptr::addr_of!((*ptr)._IO_write_base) as usize - ptr as usize },
|
|
||||||
32usize,
|
|
||||||
concat!(
|
|
||||||
"Offset of field: ",
|
|
||||||
stringify!(_IO_FILE),
|
|
||||||
"::",
|
|
||||||
stringify!(_IO_write_base)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
unsafe { ::std::ptr::addr_of!((*ptr)._IO_write_ptr) as usize - ptr as usize },
|
|
||||||
40usize,
|
|
||||||
concat!(
|
|
||||||
"Offset of field: ",
|
|
||||||
stringify!(_IO_FILE),
|
|
||||||
"::",
|
|
||||||
stringify!(_IO_write_ptr)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
unsafe { ::std::ptr::addr_of!((*ptr)._IO_write_end) as usize - ptr as usize },
|
|
||||||
48usize,
|
|
||||||
concat!(
|
|
||||||
"Offset of field: ",
|
|
||||||
stringify!(_IO_FILE),
|
|
||||||
"::",
|
|
||||||
stringify!(_IO_write_end)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
unsafe { ::std::ptr::addr_of!((*ptr)._IO_buf_base) as usize - ptr as usize },
|
|
||||||
56usize,
|
|
||||||
concat!(
|
|
||||||
"Offset of field: ",
|
|
||||||
stringify!(_IO_FILE),
|
|
||||||
"::",
|
|
||||||
stringify!(_IO_buf_base)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
unsafe { ::std::ptr::addr_of!((*ptr)._IO_buf_end) as usize - ptr as usize },
|
|
||||||
64usize,
|
|
||||||
concat!(
|
|
||||||
"Offset of field: ",
|
|
||||||
stringify!(_IO_FILE),
|
|
||||||
"::",
|
|
||||||
stringify!(_IO_buf_end)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
unsafe { ::std::ptr::addr_of!((*ptr)._IO_save_base) as usize - ptr as usize },
|
|
||||||
72usize,
|
|
||||||
concat!(
|
|
||||||
"Offset of field: ",
|
|
||||||
stringify!(_IO_FILE),
|
|
||||||
"::",
|
|
||||||
stringify!(_IO_save_base)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
unsafe { ::std::ptr::addr_of!((*ptr)._IO_backup_base) as usize - ptr as usize },
|
|
||||||
80usize,
|
|
||||||
concat!(
|
|
||||||
"Offset of field: ",
|
|
||||||
stringify!(_IO_FILE),
|
|
||||||
"::",
|
|
||||||
stringify!(_IO_backup_base)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
unsafe { ::std::ptr::addr_of!((*ptr)._IO_save_end) as usize - ptr as usize },
|
|
||||||
88usize,
|
|
||||||
concat!(
|
|
||||||
"Offset of field: ",
|
|
||||||
stringify!(_IO_FILE),
|
|
||||||
"::",
|
|
||||||
stringify!(_IO_save_end)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
unsafe { ::std::ptr::addr_of!((*ptr)._markers) as usize - ptr as usize },
|
|
||||||
96usize,
|
|
||||||
concat!(
|
|
||||||
"Offset of field: ",
|
|
||||||
stringify!(_IO_FILE),
|
|
||||||
"::",
|
|
||||||
stringify!(_markers)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
unsafe { ::std::ptr::addr_of!((*ptr)._chain) as usize - ptr as usize },
|
|
||||||
104usize,
|
|
||||||
concat!(
|
|
||||||
"Offset of field: ",
|
|
||||||
stringify!(_IO_FILE),
|
|
||||||
"::",
|
|
||||||
stringify!(_chain)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
unsafe { ::std::ptr::addr_of!((*ptr)._fileno) as usize - ptr as usize },
|
|
||||||
112usize,
|
|
||||||
concat!(
|
|
||||||
"Offset of field: ",
|
|
||||||
stringify!(_IO_FILE),
|
|
||||||
"::",
|
|
||||||
stringify!(_fileno)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
unsafe { ::std::ptr::addr_of!((*ptr)._flags2) as usize - ptr as usize },
|
|
||||||
116usize,
|
|
||||||
concat!(
|
|
||||||
"Offset of field: ",
|
|
||||||
stringify!(_IO_FILE),
|
|
||||||
"::",
|
|
||||||
stringify!(_flags2)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
unsafe { ::std::ptr::addr_of!((*ptr)._old_offset) as usize - ptr as usize },
|
|
||||||
120usize,
|
|
||||||
concat!(
|
|
||||||
"Offset of field: ",
|
|
||||||
stringify!(_IO_FILE),
|
|
||||||
"::",
|
|
||||||
stringify!(_old_offset)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
unsafe { ::std::ptr::addr_of!((*ptr)._cur_column) as usize - ptr as usize },
|
|
||||||
128usize,
|
|
||||||
concat!(
|
|
||||||
"Offset of field: ",
|
|
||||||
stringify!(_IO_FILE),
|
|
||||||
"::",
|
|
||||||
stringify!(_cur_column)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
unsafe { ::std::ptr::addr_of!((*ptr)._vtable_offset) as usize - ptr as usize },
|
|
||||||
130usize,
|
|
||||||
concat!(
|
|
||||||
"Offset of field: ",
|
|
||||||
stringify!(_IO_FILE),
|
|
||||||
"::",
|
|
||||||
stringify!(_vtable_offset)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
unsafe { ::std::ptr::addr_of!((*ptr)._shortbuf) as usize - ptr as usize },
|
|
||||||
131usize,
|
|
||||||
concat!(
|
|
||||||
"Offset of field: ",
|
|
||||||
stringify!(_IO_FILE),
|
|
||||||
"::",
|
|
||||||
stringify!(_shortbuf)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
unsafe { ::std::ptr::addr_of!((*ptr)._lock) as usize - ptr as usize },
|
|
||||||
136usize,
|
|
||||||
concat!(
|
|
||||||
"Offset of field: ",
|
|
||||||
stringify!(_IO_FILE),
|
|
||||||
"::",
|
|
||||||
stringify!(_lock)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
unsafe { ::std::ptr::addr_of!((*ptr)._offset) as usize - ptr as usize },
|
|
||||||
144usize,
|
|
||||||
concat!(
|
|
||||||
"Offset of field: ",
|
|
||||||
stringify!(_IO_FILE),
|
|
||||||
"::",
|
|
||||||
stringify!(_offset)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
unsafe { ::std::ptr::addr_of!((*ptr)._codecvt) as usize - ptr as usize },
|
|
||||||
152usize,
|
|
||||||
concat!(
|
|
||||||
"Offset of field: ",
|
|
||||||
stringify!(_IO_FILE),
|
|
||||||
"::",
|
|
||||||
stringify!(_codecvt)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
unsafe { ::std::ptr::addr_of!((*ptr)._wide_data) as usize - ptr as usize },
|
|
||||||
160usize,
|
|
||||||
concat!(
|
|
||||||
"Offset of field: ",
|
|
||||||
stringify!(_IO_FILE),
|
|
||||||
"::",
|
|
||||||
stringify!(_wide_data)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
unsafe { ::std::ptr::addr_of!((*ptr)._freeres_list) as usize - ptr as usize },
|
|
||||||
168usize,
|
|
||||||
concat!(
|
|
||||||
"Offset of field: ",
|
|
||||||
stringify!(_IO_FILE),
|
|
||||||
"::",
|
|
||||||
stringify!(_freeres_list)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
unsafe { ::std::ptr::addr_of!((*ptr)._freeres_buf) as usize - ptr as usize },
|
|
||||||
176usize,
|
|
||||||
concat!(
|
|
||||||
"Offset of field: ",
|
|
||||||
stringify!(_IO_FILE),
|
|
||||||
"::",
|
|
||||||
stringify!(_freeres_buf)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
unsafe { ::std::ptr::addr_of!((*ptr)._prevchain) as usize - ptr as usize },
|
|
||||||
184usize,
|
|
||||||
concat!(
|
|
||||||
"Offset of field: ",
|
|
||||||
stringify!(_IO_FILE),
|
|
||||||
"::",
|
|
||||||
stringify!(_prevchain)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
unsafe { ::std::ptr::addr_of!((*ptr)._mode) as usize - ptr as usize },
|
|
||||||
192usize,
|
|
||||||
concat!(
|
|
||||||
"Offset of field: ",
|
|
||||||
stringify!(_IO_FILE),
|
|
||||||
"::",
|
|
||||||
stringify!(_mode)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
unsafe { ::std::ptr::addr_of!((*ptr)._unused2) as usize - ptr as usize },
|
|
||||||
196usize,
|
|
||||||
concat!(
|
|
||||||
"Offset of field: ",
|
|
||||||
stringify!(_IO_FILE),
|
|
||||||
"::",
|
|
||||||
stringify!(_unused2)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
impl Default for _IO_FILE {
|
impl Default for _IO_FILE {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
|
let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
|
||||||
@ -920,62 +543,21 @@ pub struct _IO_cookie_io_functions_t {
|
|||||||
pub seek: cookie_seek_function_t,
|
pub seek: cookie_seek_function_t,
|
||||||
pub close: cookie_close_function_t,
|
pub close: cookie_close_function_t,
|
||||||
}
|
}
|
||||||
#[test]
|
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
|
||||||
fn bindgen_test_layout__IO_cookie_io_functions_t() {
|
const _: () = {
|
||||||
const UNINIT: ::std::mem::MaybeUninit<_IO_cookie_io_functions_t> =
|
["Size of _IO_cookie_io_functions_t"]
|
||||||
::std::mem::MaybeUninit::uninit();
|
[::std::mem::size_of::<_IO_cookie_io_functions_t>() - 32usize];
|
||||||
let ptr = UNINIT.as_ptr();
|
["Alignment of _IO_cookie_io_functions_t"]
|
||||||
assert_eq!(
|
[::std::mem::align_of::<_IO_cookie_io_functions_t>() - 8usize];
|
||||||
::std::mem::size_of::<_IO_cookie_io_functions_t>(),
|
["Offset of field: _IO_cookie_io_functions_t::read"]
|
||||||
32usize,
|
[::std::mem::offset_of!(_IO_cookie_io_functions_t, read) - 0usize];
|
||||||
concat!("Size of: ", stringify!(_IO_cookie_io_functions_t))
|
["Offset of field: _IO_cookie_io_functions_t::write"]
|
||||||
);
|
[::std::mem::offset_of!(_IO_cookie_io_functions_t, write) - 8usize];
|
||||||
assert_eq!(
|
["Offset of field: _IO_cookie_io_functions_t::seek"]
|
||||||
::std::mem::align_of::<_IO_cookie_io_functions_t>(),
|
[::std::mem::offset_of!(_IO_cookie_io_functions_t, seek) - 16usize];
|
||||||
8usize,
|
["Offset of field: _IO_cookie_io_functions_t::close"]
|
||||||
concat!("Alignment of ", stringify!(_IO_cookie_io_functions_t))
|
[::std::mem::offset_of!(_IO_cookie_io_functions_t, close) - 24usize];
|
||||||
);
|
};
|
||||||
assert_eq!(
|
|
||||||
unsafe { ::std::ptr::addr_of!((*ptr).read) as usize - ptr as usize },
|
|
||||||
0usize,
|
|
||||||
concat!(
|
|
||||||
"Offset of field: ",
|
|
||||||
stringify!(_IO_cookie_io_functions_t),
|
|
||||||
"::",
|
|
||||||
stringify!(read)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
unsafe { ::std::ptr::addr_of!((*ptr).write) as usize - ptr as usize },
|
|
||||||
8usize,
|
|
||||||
concat!(
|
|
||||||
"Offset of field: ",
|
|
||||||
stringify!(_IO_cookie_io_functions_t),
|
|
||||||
"::",
|
|
||||||
stringify!(write)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
unsafe { ::std::ptr::addr_of!((*ptr).seek) as usize - ptr as usize },
|
|
||||||
16usize,
|
|
||||||
concat!(
|
|
||||||
"Offset of field: ",
|
|
||||||
stringify!(_IO_cookie_io_functions_t),
|
|
||||||
"::",
|
|
||||||
stringify!(seek)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
unsafe { ::std::ptr::addr_of!((*ptr).close) as usize - ptr as usize },
|
|
||||||
24usize,
|
|
||||||
concat!(
|
|
||||||
"Offset of field: ",
|
|
||||||
stringify!(_IO_cookie_io_functions_t),
|
|
||||||
"::",
|
|
||||||
stringify!(close)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
pub type cookie_io_functions_t = _IO_cookie_io_functions_t;
|
pub type cookie_io_functions_t = _IO_cookie_io_functions_t;
|
||||||
pub type va_list = __gnuc_va_list;
|
pub type va_list = __gnuc_va_list;
|
||||||
pub type off_t = __off_t;
|
pub type off_t = __off_t;
|
||||||
@ -1597,61 +1179,19 @@ pub struct __va_list_tag {
|
|||||||
pub overflow_arg_area: *mut ::std::os::raw::c_void,
|
pub overflow_arg_area: *mut ::std::os::raw::c_void,
|
||||||
pub reg_save_area: *mut ::std::os::raw::c_void,
|
pub reg_save_area: *mut ::std::os::raw::c_void,
|
||||||
}
|
}
|
||||||
#[test]
|
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
|
||||||
fn bindgen_test_layout___va_list_tag() {
|
const _: () = {
|
||||||
const UNINIT: ::std::mem::MaybeUninit<__va_list_tag> = ::std::mem::MaybeUninit::uninit();
|
["Size of __va_list_tag"][::std::mem::size_of::<__va_list_tag>() - 24usize];
|
||||||
let ptr = UNINIT.as_ptr();
|
["Alignment of __va_list_tag"][::std::mem::align_of::<__va_list_tag>() - 8usize];
|
||||||
assert_eq!(
|
["Offset of field: __va_list_tag::gp_offset"]
|
||||||
::std::mem::size_of::<__va_list_tag>(),
|
[::std::mem::offset_of!(__va_list_tag, gp_offset) - 0usize];
|
||||||
24usize,
|
["Offset of field: __va_list_tag::fp_offset"]
|
||||||
concat!("Size of: ", stringify!(__va_list_tag))
|
[::std::mem::offset_of!(__va_list_tag, fp_offset) - 4usize];
|
||||||
);
|
["Offset of field: __va_list_tag::overflow_arg_area"]
|
||||||
assert_eq!(
|
[::std::mem::offset_of!(__va_list_tag, overflow_arg_area) - 8usize];
|
||||||
::std::mem::align_of::<__va_list_tag>(),
|
["Offset of field: __va_list_tag::reg_save_area"]
|
||||||
8usize,
|
[::std::mem::offset_of!(__va_list_tag, reg_save_area) - 16usize];
|
||||||
concat!("Alignment of ", stringify!(__va_list_tag))
|
};
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
unsafe { ::std::ptr::addr_of!((*ptr).gp_offset) as usize - ptr as usize },
|
|
||||||
0usize,
|
|
||||||
concat!(
|
|
||||||
"Offset of field: ",
|
|
||||||
stringify!(__va_list_tag),
|
|
||||||
"::",
|
|
||||||
stringify!(gp_offset)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
unsafe { ::std::ptr::addr_of!((*ptr).fp_offset) as usize - ptr as usize },
|
|
||||||
4usize,
|
|
||||||
concat!(
|
|
||||||
"Offset of field: ",
|
|
||||||
stringify!(__va_list_tag),
|
|
||||||
"::",
|
|
||||||
stringify!(fp_offset)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
unsafe { ::std::ptr::addr_of!((*ptr).overflow_arg_area) as usize - ptr as usize },
|
|
||||||
8usize,
|
|
||||||
concat!(
|
|
||||||
"Offset of field: ",
|
|
||||||
stringify!(__va_list_tag),
|
|
||||||
"::",
|
|
||||||
stringify!(overflow_arg_area)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
unsafe { ::std::ptr::addr_of!((*ptr).reg_save_area) as usize - ptr as usize },
|
|
||||||
16usize,
|
|
||||||
concat!(
|
|
||||||
"Offset of field: ",
|
|
||||||
stringify!(__va_list_tag),
|
|
||||||
"::",
|
|
||||||
stringify!(reg_save_area)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
impl Default for __va_list_tag {
|
impl Default for __va_list_tag {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
|
let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
|
||||||
|
@ -84,7 +84,7 @@ impl crate::ArchExtras for crate::CPU {
|
|||||||
{
|
{
|
||||||
let stack_ptr: GuestReg = self.read_reg(Regs::Rsp)?;
|
let stack_ptr: GuestReg = self.read_reg(Regs::Rsp)?;
|
||||||
let mut ret_addr = [0; size_of::<GuestReg>()];
|
let mut ret_addr = [0; size_of::<GuestReg>()];
|
||||||
unsafe { self.read_mem(stack_ptr, &mut ret_addr) };
|
unsafe { self.read_mem_unchecked(stack_ptr, &mut ret_addr) };
|
||||||
Ok(GuestReg::from_le_bytes(ret_addr).into())
|
Ok(GuestReg::from_le_bytes(ret_addr).into())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,7 +95,7 @@ impl crate::ArchExtras for crate::CPU {
|
|||||||
let stack_ptr: GuestReg = self.read_reg(Regs::Rsp)?;
|
let stack_ptr: GuestReg = self.read_reg(Regs::Rsp)?;
|
||||||
let val: GuestReg = val.into();
|
let val: GuestReg = val.into();
|
||||||
let ret_addr = val.to_le_bytes();
|
let ret_addr = val.to_le_bytes();
|
||||||
unsafe { self.write_mem(stack_ptr, &ret_addr) };
|
unsafe { self.write_mem_unchecked(stack_ptr, &ret_addr) };
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -380,7 +380,10 @@ where
|
|||||||
) -> Result<Option<EmulatorDriverResult<CM, ED, ET, S, SM>>, EmulatorDriverError> {
|
) -> Result<Option<EmulatorDriverResult<CM, ED, ET, S, SM>>, EmulatorDriverError> {
|
||||||
let qemu = emu.qemu();
|
let qemu = emu.qemu();
|
||||||
|
|
||||||
let ret_value = self.location.write(qemu, input.target_bytes().as_slice());
|
let ret_value = self
|
||||||
|
.location
|
||||||
|
.write(qemu, input.target_bytes().as_slice())
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
if let Some(reg) = ret_reg {
|
if let Some(reg) = ret_reg {
|
||||||
self.cpu.write_reg(reg, ret_value).unwrap();
|
self.cpu.write_reg(reg, ret_value).unwrap();
|
||||||
@ -443,7 +446,8 @@ where
|
|||||||
// Write input to input location
|
// Write input to input location
|
||||||
let ret_value = self
|
let ret_value = self
|
||||||
.input_location
|
.input_location
|
||||||
.write(qemu, input.target_bytes().as_slice());
|
.write(qemu, input.target_bytes().as_slice())
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
// Unleash hooks if locked
|
// Unleash hooks if locked
|
||||||
if emu.driver_mut().unlock_hooks() {
|
if emu.driver_mut().unlock_hooks() {
|
||||||
|
@ -298,7 +298,7 @@ where
|
|||||||
|
|
||||||
let mem_chunk =
|
let mem_chunk =
|
||||||
QemuMemoryChunk::virt(buf_addr as GuestVirtAddr, total_size as GuestReg, cpu);
|
QemuMemoryChunk::virt(buf_addr as GuestVirtAddr, total_size as GuestReg, cpu);
|
||||||
mem_chunk.read(qemu, str_copy.as_slice_mut());
|
mem_chunk.read(qemu, str_copy.as_slice_mut())?;
|
||||||
|
|
||||||
let c_str: &CStr = CStr::from_bytes_with_nul(str_copy.as_slice()).unwrap();
|
let c_str: &CStr = CStr::from_bytes_with_nul(str_copy.as_slice()).unwrap();
|
||||||
|
|
||||||
@ -325,7 +325,7 @@ where
|
|||||||
|
|
||||||
Ok(TestCommand::new(
|
Ok(TestCommand::new(
|
||||||
received_value,
|
received_value,
|
||||||
bindings::LIBAFL_QEMU_TEST_VALUE as GuestReg,
|
GuestReg::from(bindings::LIBAFL_QEMU_TEST_VALUE),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,8 @@ where
|
|||||||
func(emulator_modules, target_sig);
|
func(emulator_modules, target_sig);
|
||||||
}
|
}
|
||||||
HookRepr::Closure(ptr) => {
|
HookRepr::Closure(ptr) => {
|
||||||
let func: &mut CrashHookClosure<ET, S> = transmute(ptr);
|
let func: &mut CrashHookClosure<ET, S> =
|
||||||
|
&mut *(ptr::from_mut::<FatPtr>(ptr) as *mut CrashHookClosure<ET, S>);
|
||||||
func(emulator_modules, target_sig);
|
func(emulator_modules, target_sig);
|
||||||
}
|
}
|
||||||
HookRepr::Empty => (),
|
HookRepr::Empty => (),
|
||||||
|
@ -56,8 +56,11 @@ where
|
|||||||
first_exec: bool,
|
first_exec: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// This should be used as a crash handler, and nothing else.
|
||||||
#[cfg(emulation_mode = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
pub unsafe fn inproc_qemu_crash_handler(
|
unsafe fn inproc_qemu_crash_handler(
|
||||||
signal: Signal,
|
signal: Signal,
|
||||||
info: &mut siginfo_t,
|
info: &mut siginfo_t,
|
||||||
mut context: Option<&mut ucontext_t>,
|
mut context: Option<&mut ucontext_t>,
|
||||||
@ -329,6 +332,7 @@ where
|
|||||||
Z: HasObjective<State = S>,
|
Z: HasObjective<State = S>,
|
||||||
Z::Objective: Feedback<EM, S::Input, OT, S>,
|
Z::Objective: Feedback<EM, S::Input, OT, S>,
|
||||||
{
|
{
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn new(
|
pub fn new(
|
||||||
emulator: Emulator<CM, ED, ET, S, SM>,
|
emulator: Emulator<CM, ED, ET, S, SM>,
|
||||||
harness_fn: &'a mut H,
|
harness_fn: &'a mut H,
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
/*! */
|
/*! */
|
||||||
#![doc = include_str!("../README.md")]
|
#![doc = include_str!("../README.md")]
|
||||||
#![cfg_attr(feature = "document-features", doc = document_features::document_features!())]
|
#![cfg_attr(feature = "document-features", doc = document_features::document_features!())]
|
||||||
#![forbid(unexpected_cfgs)]
|
|
||||||
// libafl_qemu only supports Linux currently
|
// libafl_qemu only supports Linux currently
|
||||||
#![cfg(target_os = "linux")]
|
#![cfg(target_os = "linux")]
|
||||||
// This lint triggers too often on the current GuestAddr type when emulating 64-bit targets because
|
// This lint triggers too often on the current GuestAddr type when emulating 64-bit targets because
|
||||||
@ -13,16 +12,6 @@
|
|||||||
any(cpu_target = "x86_64", cpu_target = "aarch64"),
|
any(cpu_target = "x86_64", cpu_target = "aarch64"),
|
||||||
allow(clippy::useless_conversion)
|
allow(clippy::useless_conversion)
|
||||||
)]
|
)]
|
||||||
#![allow(clippy::needless_pass_by_value)]
|
|
||||||
#![allow(clippy::needless_pass_by_ref_mut)]
|
|
||||||
#![allow(clippy::transmute_ptr_to_ptr)]
|
|
||||||
#![allow(clippy::ptr_cast_constness)]
|
|
||||||
#![allow(clippy::too_many_arguments)]
|
|
||||||
// Till they fix this buggy lint in clippy
|
|
||||||
#![allow(clippy::borrow_as_ptr)]
|
|
||||||
#![allow(clippy::borrow_deref_ref)]
|
|
||||||
// Allow only ATM, it will be evetually removed
|
|
||||||
#![allow(clippy::missing_safety_doc)]
|
|
||||||
// libafl_qemu_sys export types with empty struct markers (e.g. struct {} start_init_save)
|
// libafl_qemu_sys export types with empty struct markers (e.g. struct {} start_init_save)
|
||||||
// This causes bindgen to generate empty Rust struct that are generally not FFI-safe due to C++ having empty structs with size 1
|
// This causes bindgen to generate empty Rust struct that are generally not FFI-safe due to C++ having empty structs with size 1
|
||||||
// As the QEMU codebase is C, it is FFI-safe and we just ignore the warning
|
// As the QEMU codebase is C, it is FFI-safe and we just ignore the warning
|
||||||
|
@ -646,8 +646,9 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// # Safety
|
/// # Safety
|
||||||
// Calling this concurrently for the same id is racey and may lose updates.
|
///
|
||||||
|
/// Calling this concurrently for the same id is racey and may lose updates.
|
||||||
pub unsafe extern "C" fn trace_edge_hitcount(_: *const (), id: u64) {
|
pub unsafe extern "C" fn trace_edge_hitcount(_: *const (), id: u64) {
|
||||||
unsafe {
|
unsafe {
|
||||||
EDGES_MAP[id as usize] = EDGES_MAP[id as usize].wrapping_add(1);
|
EDGES_MAP[id as usize] = EDGES_MAP[id as usize].wrapping_add(1);
|
||||||
|
@ -751,14 +751,14 @@ pub struct AsanModule {
|
|||||||
impl AsanModule {
|
impl AsanModule {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn default(rt: Pin<Box<AsanGiovese>>) -> Self {
|
pub fn default(rt: Pin<Box<AsanGiovese>>) -> Self {
|
||||||
Self::new(rt, StdAddressFilter::default(), QemuAsanOptions::Snapshot)
|
Self::new(rt, StdAddressFilter::default(), &QemuAsanOptions::Snapshot)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new(
|
pub fn new(
|
||||||
mut rt: Pin<Box<AsanGiovese>>,
|
mut rt: Pin<Box<AsanGiovese>>,
|
||||||
filter: StdAddressFilter,
|
filter: StdAddressFilter,
|
||||||
options: QemuAsanOptions,
|
options: &QemuAsanOptions,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
assert!(unsafe { ASAN_INITED }, "The ASan runtime is not initialized, use init_qemu_with_asan(...) instead of just Qemu::init(...)");
|
assert!(unsafe { ASAN_INITED }, "The ASan runtime is not initialized, use init_qemu_with_asan(...) instead of just Qemu::init(...)");
|
||||||
let (snapshot, detect_leaks) = match options {
|
let (snapshot, detect_leaks) = match options {
|
||||||
@ -782,7 +782,7 @@ impl AsanModule {
|
|||||||
mut rt: Pin<Box<AsanGiovese>>,
|
mut rt: Pin<Box<AsanGiovese>>,
|
||||||
filter: StdAddressFilter,
|
filter: StdAddressFilter,
|
||||||
error_callback: AsanErrorCallback,
|
error_callback: AsanErrorCallback,
|
||||||
options: QemuAsanOptions,
|
options: &QemuAsanOptions,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
assert!(unsafe { ASAN_INITED }, "The ASan runtime is not initialized, use init_qemu_with_asan(...) instead of just Qemu::init(...)");
|
assert!(unsafe { ASAN_INITED }, "The ASan runtime is not initialized, use init_qemu_with_asan(...) instead of just Qemu::init(...)");
|
||||||
let (snapshot, detect_leaks) = match options {
|
let (snapshot, detect_leaks) = match options {
|
||||||
@ -808,12 +808,12 @@ impl AsanModule {
|
|||||||
pub unsafe fn with_asan_report(
|
pub unsafe fn with_asan_report(
|
||||||
rt: Pin<Box<AsanGiovese>>,
|
rt: Pin<Box<AsanGiovese>>,
|
||||||
filter: StdAddressFilter,
|
filter: StdAddressFilter,
|
||||||
options: QemuAsanOptions,
|
options: &QemuAsanOptions,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self::with_error_callback(
|
Self::with_error_callback(
|
||||||
rt,
|
rt,
|
||||||
filter,
|
filter,
|
||||||
Box::new(|rt, qemu, pc, err| unsafe { asan_report(rt, qemu, pc, err) }),
|
Box::new(|rt, qemu, pc, err| unsafe { asan_report(rt, qemu, pc, &err) }),
|
||||||
options,
|
options,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -1536,7 +1536,7 @@ mod addr2line_legacy {
|
|||||||
/// Calling this function concurrently might be racey.
|
/// Calling this function concurrently might be racey.
|
||||||
#[allow(clippy::unnecessary_cast)]
|
#[allow(clippy::unnecessary_cast)]
|
||||||
#[allow(clippy::too_many_lines)]
|
#[allow(clippy::too_many_lines)]
|
||||||
pub unsafe fn asan_report(rt: &AsanGiovese, qemu: Qemu, pc: GuestAddr, err: AsanError) {
|
pub unsafe fn asan_report(rt: &AsanGiovese, qemu: Qemu, pc: GuestAddr, err: &AsanError) {
|
||||||
let mut regions = HashMap::new();
|
let mut regions = HashMap::new();
|
||||||
for region in qemu.mappings() {
|
for region in qemu.mappings() {
|
||||||
if let Some(path) = region.path() {
|
if let Some(path) = region.path() {
|
||||||
@ -1668,7 +1668,7 @@ pub unsafe fn asan_report(rt: &AsanGiovese, qemu: Qemu, pc: GuestAddr, err: Asan
|
|||||||
}
|
}
|
||||||
let addr = match err {
|
let addr = match err {
|
||||||
AsanError::Read(addr, _) | AsanError::Write(addr, _) | AsanError::BadFree(addr, _) => {
|
AsanError::Read(addr, _) | AsanError::Write(addr, _) | AsanError::BadFree(addr, _) => {
|
||||||
Some(addr)
|
Some(*addr)
|
||||||
}
|
}
|
||||||
AsanError::MemLeak(_) | AsanError::Signal(_) => None,
|
AsanError::MemLeak(_) | AsanError::Signal(_) => None,
|
||||||
};
|
};
|
||||||
|
@ -146,7 +146,7 @@ impl<F> AsanGuestModule<F> {
|
|||||||
|
|
||||||
impl AsanGuestModule<StdAddressFilter> {
|
impl AsanGuestModule<StdAddressFilter> {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn default(qemu: Qemu, asan: String) -> Self {
|
pub fn default(qemu: Qemu, asan: &str) -> Self {
|
||||||
Self::new(qemu, asan, StdAddressFilter::default())
|
Self::new(qemu, asan, StdAddressFilter::default())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -156,7 +156,7 @@ where
|
|||||||
F: AddressFilter,
|
F: AddressFilter,
|
||||||
{
|
{
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new(qemu: Qemu, asan: String, filter: F) -> Self {
|
pub fn new(qemu: Qemu, asan: &str, filter: F) -> Self {
|
||||||
for mapping in qemu.mappings() {
|
for mapping in qemu.mappings() {
|
||||||
println!("mapping: {mapping:#?}");
|
println!("mapping: {mapping:#?}");
|
||||||
}
|
}
|
||||||
|
@ -343,6 +343,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn syscall_hook<ET, S>(
|
fn syscall_hook<ET, S>(
|
||||||
emulator_modules: &mut EmulatorModules<ET, S>, // our instantiated QemuHooks
|
emulator_modules: &mut EmulatorModules<ET, S>, // our instantiated QemuHooks
|
||||||
_state: Option<&mut S>,
|
_state: Option<&mut S>,
|
||||||
|
@ -208,7 +208,7 @@ impl SnapshotModule {
|
|||||||
// TODO not just for R pages
|
// TODO not just for R pages
|
||||||
unsafe {
|
unsafe {
|
||||||
info.data = Some(Box::new(core::mem::zeroed()));
|
info.data = Some(Box::new(core::mem::zeroed()));
|
||||||
qemu.read_mem(addr, &mut info.data.as_mut().unwrap()[..]);
|
qemu.read_mem_unchecked(addr, &mut info.data.as_mut().unwrap()[..]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.pages.insert(addr, info);
|
self.pages.insert(addr, info);
|
||||||
@ -299,7 +299,8 @@ impl SnapshotModule {
|
|||||||
qemu.read_mem(
|
qemu.read_mem(
|
||||||
addr,
|
addr,
|
||||||
current_page_content.as_mut_ptr().as_mut().unwrap(),
|
current_page_content.as_mut_ptr().as_mut().unwrap(),
|
||||||
);
|
)
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
let current_page_content: &mut [u8; SNAPSHOT_PAGE_SIZE] =
|
let current_page_content: &mut [u8; SNAPSHOT_PAGE_SIZE] =
|
||||||
@ -411,7 +412,7 @@ impl SnapshotModule {
|
|||||||
return true; // Restore later
|
return true; // Restore later
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe { qemu.write_mem(*page, &data[..]) };
|
unsafe { qemu.write_mem_unchecked(*page, &data[..]) };
|
||||||
} else {
|
} else {
|
||||||
panic!("Cannot restored a dirty but unsaved page");
|
panic!("Cannot restored a dirty but unsaved page");
|
||||||
}
|
}
|
||||||
@ -446,7 +447,7 @@ impl SnapshotModule {
|
|||||||
if let Some(info) = self.pages.get_mut(page) {
|
if let Some(info) = self.pages.get_mut(page) {
|
||||||
// TODO avoid duplicated memcpy
|
// TODO avoid duplicated memcpy
|
||||||
if let Some(data) = info.data.as_ref() {
|
if let Some(data) = info.data.as_ref() {
|
||||||
unsafe { qemu.write_mem(*page, &data[..]) };
|
unsafe { qemu.write_mem_unchecked(*page, &data[..]) };
|
||||||
} else {
|
} else {
|
||||||
panic!("Cannot restored a dirty but unsaved page");
|
panic!("Cannot restored a dirty but unsaved page");
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
//! The high-level hooks
|
//! The high-level hooks
|
||||||
#![allow(clippy::type_complexity, clippy::missing_transmute_annotations)]
|
#![allow(clippy::type_complexity)]
|
||||||
|
#![allow(clippy::missing_transmute_annotations)]
|
||||||
|
#![allow(clippy::too_many_arguments)]
|
||||||
|
|
||||||
use core::{ffi::c_void, fmt::Debug, mem::transmute, ptr};
|
use core::{ffi::c_void, fmt::Debug, mem::transmute, ptr};
|
||||||
|
|
||||||
@ -52,6 +54,9 @@ impl<const N: usize, H: HookId> TcgHookState<N, H> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// ids should be in sync with QEMU hooks ids.
|
||||||
pub unsafe fn set_id(&mut self, id: H) {
|
pub unsafe fn set_id(&mut self, id: H) {
|
||||||
self.id = id;
|
self.id = id;
|
||||||
}
|
}
|
||||||
@ -66,6 +71,9 @@ impl<H: HookId> HookState<H> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// ids should be in sync with QEMU hooks ids.
|
||||||
pub unsafe fn set_id(&mut self, id: H) {
|
pub unsafe fn set_id(&mut self, id: H) {
|
||||||
self.id = id;
|
self.id = id;
|
||||||
}
|
}
|
||||||
@ -112,7 +120,7 @@ macro_rules! create_wrapper {
|
|||||||
{
|
{
|
||||||
unsafe {
|
unsafe {
|
||||||
let modules = EmulatorModules::<ET, S>::emulator_modules_mut_unchecked();
|
let modules = EmulatorModules::<ET, S>::emulator_modules_mut_unchecked();
|
||||||
let func: &mut Box<dyn FnMut(&mut EmulatorModules<ET, S>, Option<&mut S>, $($param_type),*)> = transmute(hook);
|
let func: &mut Box<dyn FnMut(&mut EmulatorModules<ET, S>, Option<&mut S>, $($param_type),*)> = &mut *(ptr::from_mut::<FatPtr>(hook) as *mut Box<dyn FnMut(&mut EmulatorModules<ET, S>, Option<&mut S>, $($param_type),*)>);
|
||||||
func(modules, inprocess_get_state::<S>(), $($param),*);
|
func(modules, inprocess_get_state::<S>(), $($param),*);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -137,7 +145,7 @@ macro_rules! create_wrapper {
|
|||||||
{
|
{
|
||||||
unsafe {
|
unsafe {
|
||||||
let modules = EmulatorModules::<ET, S>::emulator_modules_mut_unchecked();
|
let modules = EmulatorModules::<ET, S>::emulator_modules_mut_unchecked();
|
||||||
let func: &mut Box<dyn FnMut(&mut EmulatorModules<ET, S>, Option<&mut S>, $($param_type),*) -> $ret_type> = transmute(hook);
|
let func: &mut Box<dyn FnMut(&mut EmulatorModules<ET, S>, Option<&mut S>, $($param_type),*) -> $ret_type> = &mut *(ptr::from_mut::<FatPtr>(hook) as *mut Box<dyn FnMut(&mut EmulatorModules<ET, S>, Option<&mut S>, $($param_type),*) -> $ret_type>);
|
||||||
func(modules, inprocess_get_state::<S>(), $($param),*)
|
func(modules, inprocess_get_state::<S>(), $($param),*)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -164,7 +172,9 @@ macro_rules! create_pre_exec_wrapper {
|
|||||||
HookRepr::Closure(ptr) => {
|
HookRepr::Closure(ptr) => {
|
||||||
let func: &mut Box<
|
let func: &mut Box<
|
||||||
dyn FnMut(&mut EmulatorModules<ET, S>, Option<&mut S>, $($param_type),*),
|
dyn FnMut(&mut EmulatorModules<ET, S>, Option<&mut S>, $($param_type),*),
|
||||||
> = transmute(ptr);
|
> = &mut *(ptr::from_mut::<FatPtr>(ptr) as *mut Box<
|
||||||
|
dyn FnMut(&mut EmulatorModules<ET, S>, Option<&mut S>, $($param_type),*),
|
||||||
|
>);
|
||||||
func(modules, inprocess_get_state::<S>(), $($param),*)
|
func(modules, inprocess_get_state::<S>(), $($param),*)
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
@ -194,7 +204,9 @@ macro_rules! create_post_exec_wrapper {
|
|||||||
HookRepr::Closure(ptr) => {
|
HookRepr::Closure(ptr) => {
|
||||||
let func: &mut Box<
|
let func: &mut Box<
|
||||||
dyn FnMut(&mut EmulatorModules<ET, S>, Option<&mut S>, $($param_type),*),
|
dyn FnMut(&mut EmulatorModules<ET, S>, Option<&mut S>, $($param_type),*),
|
||||||
> = transmute(ptr);
|
> = &mut *(ptr::from_mut::<FatPtr>(ptr) as *mut Box<
|
||||||
|
dyn FnMut(&mut EmulatorModules<ET, S>, Option<&mut S>, $($param_type),*),
|
||||||
|
>);
|
||||||
func(modules, inprocess_get_state::<S>(), $($param),*);
|
func(modules, inprocess_get_state::<S>(), $($param),*);
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
@ -224,7 +236,7 @@ macro_rules! create_gen_wrapper {
|
|||||||
HookRepr::Closure(ptr) => {
|
HookRepr::Closure(ptr) => {
|
||||||
let func: &mut Box<
|
let func: &mut Box<
|
||||||
dyn FnMut(&mut EmulatorModules<ET, S>, Option<&mut S>, $($param_type),*) -> Option<$ret_type>,
|
dyn FnMut(&mut EmulatorModules<ET, S>, Option<&mut S>, $($param_type),*) -> Option<$ret_type>,
|
||||||
> = transmute(ptr);
|
> = &mut *(ptr::from_mut::<FatPtr>(ptr) as *mut Box<dyn FnMut(&mut EmulatorModules<ET, S>, Option<&mut S>, $($param_type),*) -> Option<$ret_type>>);
|
||||||
func(modules, inprocess_get_state::<S>(), $($param),*).map_or(SKIP_EXEC_HOOK, |id| id)
|
func(modules, inprocess_get_state::<S>(), $($param),*).map_or(SKIP_EXEC_HOOK, |id| id)
|
||||||
}
|
}
|
||||||
_ => 0,
|
_ => 0,
|
||||||
@ -253,7 +265,7 @@ macro_rules! create_post_gen_wrapper {
|
|||||||
HookRepr::Closure(ptr) => {
|
HookRepr::Closure(ptr) => {
|
||||||
let func: &mut Box<
|
let func: &mut Box<
|
||||||
dyn FnMut(&mut EmulatorModules<ET, S>, Option<&mut S>, $($param_type),*),
|
dyn FnMut(&mut EmulatorModules<ET, S>, Option<&mut S>, $($param_type),*),
|
||||||
> = transmute(ptr);
|
> = &mut *(ptr::from_mut::<FatPtr>(ptr) as *mut Box<dyn FnMut(&mut EmulatorModules<ET, S>, Option<&mut S>, $($param_type),*)>);
|
||||||
func(modules, inprocess_get_state::<S>(), $($param),*);
|
func(modules, inprocess_get_state::<S>(), $($param),*);
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
@ -280,7 +292,7 @@ macro_rules! create_exec_wrapper {
|
|||||||
}
|
}
|
||||||
HookRepr::Closure(ptr) => {
|
HookRepr::Closure(ptr) => {
|
||||||
let func: &mut Box<dyn FnMut(&mut EmulatorModules<ET, S>, Option<&mut S>, $($param_type),*)> =
|
let func: &mut Box<dyn FnMut(&mut EmulatorModules<ET, S>, Option<&mut S>, $($param_type),*)> =
|
||||||
transmute(ptr);
|
&mut *(ptr::from_mut::<FatPtr>(ptr) as *mut Box<dyn FnMut(&mut EmulatorModules<ET, S>, Option<&mut S>, $($param_type),*)>);
|
||||||
func(modules, inprocess_get_state::<S>(), $($param),*);
|
func(modules, inprocess_get_state::<S>(), $($param),*);
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
|
@ -18,8 +18,6 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use libafl_bolts::os::unix_signals::Signal;
|
use libafl_bolts::os::unix_signals::Signal;
|
||||||
#[cfg(emulation_mode = "usermode")]
|
|
||||||
use libafl_qemu_sys::{guest_base, VerifyAccess};
|
|
||||||
use libafl_qemu_sys::{
|
use libafl_qemu_sys::{
|
||||||
libafl_flush_jit, libafl_get_exit_reason, libafl_page_from_addr, libafl_qemu_add_gdb_cmd,
|
libafl_flush_jit, libafl_get_exit_reason, libafl_page_from_addr, libafl_qemu_add_gdb_cmd,
|
||||||
libafl_qemu_cpu_index, libafl_qemu_current_cpu, libafl_qemu_gdb_reply, libafl_qemu_get_cpu,
|
libafl_qemu_cpu_index, libafl_qemu_current_cpu, libafl_qemu_gdb_reply, libafl_qemu_get_cpu,
|
||||||
@ -52,6 +50,13 @@ pub use hooks::*;
|
|||||||
|
|
||||||
static mut QEMU_IS_INITIALIZED: bool = false;
|
static mut QEMU_IS_INITIALIZED: bool = false;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum QemuError {
|
||||||
|
Init(QemuInitError),
|
||||||
|
Exit(QemuExitError),
|
||||||
|
RW(QemuRWError),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum QemuInitError {
|
pub enum QemuInitError {
|
||||||
MultipleInstances,
|
MultipleInstances,
|
||||||
@ -92,6 +97,7 @@ pub enum QemuRWErrorCause {
|
|||||||
WrongArgument(i32),
|
WrongArgument(i32),
|
||||||
CurrentCpuNotFound,
|
CurrentCpuNotFound,
|
||||||
Reg(i32),
|
Reg(i32),
|
||||||
|
WrongMemoryLocation(GuestAddr, usize), // addr, size
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@ -108,6 +114,19 @@ impl QemuRWError {
|
|||||||
Self { kind, cause, cpu }
|
Self { kind, cause, cpu }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn wrong_mem_location(
|
||||||
|
kind: QemuRWErrorKind,
|
||||||
|
cpu: CPUStatePtr,
|
||||||
|
addr: GuestAddr,
|
||||||
|
size: usize,
|
||||||
|
) -> Self {
|
||||||
|
Self::new(
|
||||||
|
kind,
|
||||||
|
QemuRWErrorCause::WrongMemoryLocation(addr, size),
|
||||||
|
Some(cpu),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn current_cpu_not_found(kind: QemuRWErrorKind) -> Self {
|
pub fn current_cpu_not_found(kind: QemuRWErrorKind) -> Self {
|
||||||
Self::new(kind, QemuRWErrorCause::CurrentCpuNotFound, None)
|
Self::new(kind, QemuRWErrorCause::CurrentCpuNotFound, None)
|
||||||
@ -323,27 +342,6 @@ impl CPU {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(emulation_mode = "usermode")]
|
|
||||||
#[must_use]
|
|
||||||
pub fn g2h<T>(&self, addr: GuestAddr) -> *mut T {
|
|
||||||
unsafe { (addr as usize + guest_base) as *mut T }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(emulation_mode = "usermode")]
|
|
||||||
#[must_use]
|
|
||||||
pub fn h2g<T>(&self, addr: *const T) -> GuestAddr {
|
|
||||||
unsafe { (addr as usize - guest_base) as GuestAddr }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(emulation_mode = "usermode")]
|
|
||||||
#[must_use]
|
|
||||||
pub fn access_ok(&self, kind: VerifyAccess, addr: GuestAddr, size: usize) -> bool {
|
|
||||||
unsafe {
|
|
||||||
// TODO add support for tagged GuestAddr
|
|
||||||
libafl_qemu_sys::page_check_range(addr, size as GuestAddr, kind.into())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO expose tlb_set_dirty and tlb_reset_dirty
|
// TODO expose tlb_set_dirty and tlb_reset_dirty
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
@ -351,6 +349,31 @@ impl CPU {
|
|||||||
unsafe { libafl_qemu_num_regs(self.ptr) }
|
unsafe { libafl_qemu_num_regs(self.ptr) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn read_reg<R, T>(&self, reg: R) -> Result<T, QemuRWError>
|
||||||
|
where
|
||||||
|
R: Into<i32> + Clone,
|
||||||
|
T: From<GuestReg>,
|
||||||
|
{
|
||||||
|
unsafe {
|
||||||
|
let reg_id = reg.clone().into();
|
||||||
|
let mut val = MaybeUninit::uninit();
|
||||||
|
let success = libafl_qemu_read_reg(self.ptr, reg_id, val.as_mut_ptr() as *mut u8);
|
||||||
|
if success == 0 {
|
||||||
|
Err(QemuRWError {
|
||||||
|
kind: QemuRWErrorKind::Write,
|
||||||
|
cause: QemuRWErrorCause::Reg(reg.into()),
|
||||||
|
cpu: Some(self.ptr),
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
#[cfg(feature = "be")]
|
||||||
|
return Ok(GuestReg::from_be(val.assume_init()).into());
|
||||||
|
|
||||||
|
#[cfg(not(feature = "be"))]
|
||||||
|
return Ok(GuestReg::from_le(val.assume_init()).into());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn write_reg<R, T>(&self, reg: R, val: T) -> Result<(), QemuRWError>
|
pub fn write_reg<R, T>(&self, reg: R, val: T) -> Result<(), QemuRWError>
|
||||||
where
|
where
|
||||||
R: Into<i32> + Clone,
|
R: Into<i32> + Clone,
|
||||||
@ -376,28 +399,53 @@ impl CPU {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_reg<R, T>(&self, reg: R) -> Result<T, QemuRWError>
|
/// Read a value from a guest address, taking into account the potential MMU / MPU.
|
||||||
where
|
pub fn read_mem(&self, addr: GuestAddr, buf: &mut [u8]) -> Result<(), QemuRWError> {
|
||||||
R: Into<i32> + Clone,
|
// TODO use gdbstub's target_cpu_memory_rw_debug
|
||||||
T: From<GuestReg>,
|
let ret = unsafe {
|
||||||
{
|
libafl_qemu_sys::cpu_memory_rw_debug(
|
||||||
unsafe {
|
self.ptr,
|
||||||
let reg_id = reg.clone().into();
|
addr as GuestVirtAddr,
|
||||||
let mut val = MaybeUninit::uninit();
|
buf.as_mut_ptr() as *mut _,
|
||||||
let success = libafl_qemu_read_reg(self.ptr, reg_id, val.as_mut_ptr() as *mut u8);
|
buf.len(),
|
||||||
if success == 0 {
|
false,
|
||||||
Err(QemuRWError {
|
)
|
||||||
kind: QemuRWErrorKind::Write,
|
};
|
||||||
cause: QemuRWErrorCause::Reg(reg.into()),
|
|
||||||
cpu: Some(self.ptr),
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
#[cfg(feature = "be")]
|
|
||||||
return Ok(GuestReg::from_be(val.assume_init()).into());
|
|
||||||
|
|
||||||
#[cfg(not(feature = "be"))]
|
if ret != 0 {
|
||||||
return Ok(GuestReg::from_le(val.assume_init()).into());
|
Err(QemuRWError::wrong_mem_location(
|
||||||
}
|
QemuRWErrorKind::Read,
|
||||||
|
self.ptr,
|
||||||
|
addr,
|
||||||
|
buf.len(),
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Write a value to a guest address, taking into account the potential MMU / MPU.
|
||||||
|
pub fn write_mem(&self, addr: GuestAddr, buf: &[u8]) -> Result<(), QemuRWError> {
|
||||||
|
// TODO use gdbstub's target_cpu_memory_rw_debug
|
||||||
|
let ret = unsafe {
|
||||||
|
libafl_qemu_sys::cpu_memory_rw_debug(
|
||||||
|
self.ptr,
|
||||||
|
addr as GuestVirtAddr,
|
||||||
|
buf.as_ptr() as *mut _,
|
||||||
|
buf.len(),
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
if ret != 0 {
|
||||||
|
Err(QemuRWError::wrong_mem_location(
|
||||||
|
QemuRWErrorKind::Write,
|
||||||
|
self.ptr,
|
||||||
|
addr,
|
||||||
|
buf.len(),
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -707,21 +755,48 @@ impl Qemu {
|
|||||||
unsafe { libafl_page_from_addr(addr) }
|
unsafe { libafl_page_from_addr(addr) }
|
||||||
}
|
}
|
||||||
|
|
||||||
//#[must_use]
|
/// Read a value from a guest address, taking into account the potential indirections with the current CPU.
|
||||||
/*pub fn page_size() -> GuestUsize {
|
pub fn read_mem(&self, addr: GuestAddr, buf: &mut [u8]) -> Result<(), QemuRWError> {
|
||||||
unsafe { libafl_page_size }
|
|
||||||
}*/
|
|
||||||
|
|
||||||
pub unsafe fn write_mem(&self, addr: GuestAddr, buf: &[u8]) {
|
|
||||||
self.current_cpu()
|
self.current_cpu()
|
||||||
.unwrap_or_else(|| self.cpu_from_index(0))
|
.unwrap_or_else(|| self.cpu_from_index(0))
|
||||||
.write_mem(addr, buf);
|
.read_mem(addr, buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn read_mem(&self, addr: GuestAddr, buf: &mut [u8]) {
|
/// Write a value to a guest address, taking into account the potential indirections with the current CPU.
|
||||||
|
pub fn write_mem(&self, addr: GuestAddr, buf: &[u8]) -> Result<(), QemuRWError> {
|
||||||
self.current_cpu()
|
self.current_cpu()
|
||||||
.unwrap_or_else(|| self.cpu_from_index(0))
|
.unwrap_or_else(|| self.cpu_from_index(0))
|
||||||
.read_mem(addr, buf);
|
.write_mem(addr, buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Read a value from a guest address.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
/// In usermode, this will read from a translated guest address.
|
||||||
|
/// This may only be safely used for valid guest addresses.
|
||||||
|
///
|
||||||
|
/// In any case, no check will be performed on the correctness of the operation.
|
||||||
|
///
|
||||||
|
/// Please refer to [`CPU::read_mem`] for more details.
|
||||||
|
pub unsafe fn read_mem_unchecked(&self, addr: GuestAddr, buf: &mut [u8]) {
|
||||||
|
self.current_cpu()
|
||||||
|
.unwrap_or_else(|| self.cpu_from_index(0))
|
||||||
|
.read_mem_unchecked(addr, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Write a value to a guest address.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
/// In usermode, this will write to a translated guest address.
|
||||||
|
///
|
||||||
|
/// In any case, no check will be performed on the correctness of the operation.
|
||||||
|
///
|
||||||
|
/// This may only be safely used for valid guest addresses.
|
||||||
|
/// Please refer to [`CPU::write_mem`] for more details.
|
||||||
|
pub unsafe fn write_mem_unchecked(&self, addr: GuestAddr, buf: &[u8]) {
|
||||||
|
self.current_cpu()
|
||||||
|
.unwrap_or_else(|| self.cpu_from_index(0))
|
||||||
|
.write_mem_unchecked(addr, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
@ -779,12 +854,13 @@ impl Qemu {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn remove_hook(&self, id: impl HookId, invalidate_block: bool) -> bool {
|
pub fn remove_hook(&self, id: &impl HookId, invalidate_block: bool) -> bool {
|
||||||
id.remove(invalidate_block)
|
id.remove(invalidate_block)
|
||||||
}
|
}
|
||||||
|
|
||||||
// # Safety
|
/// # Safety
|
||||||
// Calling this multiple times concurrently will access static variables and is unsafe.
|
///
|
||||||
|
/// Calling this multiple times concurrently will access static variables and is unsafe.
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
pub unsafe fn add_gdb_cmd(&self, callback: Box<dyn FnMut(&Self, &str) -> bool>) {
|
pub unsafe fn add_gdb_cmd(&self, callback: Box<dyn FnMut(&Self, &str) -> bool>) {
|
||||||
let fat: Box<FatPtr> = Box::new(transmute::<
|
let fat: Box<FatPtr> = Box::new(transmute::<
|
||||||
@ -929,7 +1005,7 @@ impl QemuMemoryChunk {
|
|||||||
|
|
||||||
/// Returns the number of bytes effectively read.
|
/// Returns the number of bytes effectively read.
|
||||||
/// output will get chunked at `size` bytes.
|
/// output will get chunked at `size` bytes.
|
||||||
pub fn read(&self, qemu: Qemu, output: &mut [u8]) -> GuestReg {
|
pub fn read(&self, qemu: Qemu, output: &mut [u8]) -> Result<GuestReg, QemuRWError> {
|
||||||
let max_len: usize = self.size.try_into().unwrap();
|
let max_len: usize = self.size.try_into().unwrap();
|
||||||
|
|
||||||
let output_sliced = if output.len() > max_len {
|
let output_sliced = if output.len() > max_len {
|
||||||
@ -939,32 +1015,31 @@ impl QemuMemoryChunk {
|
|||||||
};
|
};
|
||||||
|
|
||||||
match self.addr {
|
match self.addr {
|
||||||
GuestAddrKind::Physical(hwaddr) => unsafe {
|
GuestAddrKind::Physical(hwaddr) => {
|
||||||
#[cfg(emulation_mode = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
{
|
{
|
||||||
// For now the default behaviour is to fall back to virtual addresses
|
// For now the default behaviour is to fall back to virtual addresses
|
||||||
qemu.read_mem(hwaddr.try_into().unwrap(), output_sliced);
|
qemu.read_mem(hwaddr.try_into().unwrap(), output_sliced)?;
|
||||||
}
|
}
|
||||||
#[cfg(emulation_mode = "systemmode")]
|
#[cfg(emulation_mode = "systemmode")]
|
||||||
{
|
unsafe {
|
||||||
qemu.read_phys_mem(hwaddr, output_sliced);
|
qemu.read_phys_mem(hwaddr, output_sliced);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
GuestAddrKind::Virtual(vaddr) => unsafe {
|
GuestAddrKind::Virtual(vaddr) => unsafe {
|
||||||
self.cpu
|
self.cpu
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.read_mem(vaddr.try_into().unwrap(), output_sliced);
|
.read_mem_unchecked(vaddr.try_into().unwrap(), output_sliced);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
output_sliced.len().try_into().unwrap()
|
Ok(output_sliced.len().try_into().unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the number of bytes effectively written.
|
/// Returns the number of bytes effectively written.
|
||||||
/// Input will get chunked at `size` bytes.
|
/// Input will get chunked at `size` bytes.
|
||||||
#[must_use]
|
pub fn write(&self, qemu: Qemu, input: &[u8]) -> Result<GuestReg, QemuRWError> {
|
||||||
pub fn write(&self, qemu: Qemu, input: &[u8]) -> GuestReg {
|
|
||||||
let max_len: usize = self.size.try_into().unwrap();
|
let max_len: usize = self.size.try_into().unwrap();
|
||||||
|
|
||||||
let input_sliced = if input.len() > max_len {
|
let input_sliced = if input.len() > max_len {
|
||||||
@ -974,26 +1049,26 @@ impl QemuMemoryChunk {
|
|||||||
};
|
};
|
||||||
|
|
||||||
match self.addr {
|
match self.addr {
|
||||||
GuestAddrKind::Physical(hwaddr) => unsafe {
|
GuestAddrKind::Physical(hwaddr) => {
|
||||||
#[cfg(emulation_mode = "usermode")]
|
#[cfg(emulation_mode = "usermode")]
|
||||||
{
|
{
|
||||||
// For now the default behaviour is to fall back to virtual addresses
|
// For now the default behaviour is to fall back to virtual addresses
|
||||||
qemu.write_mem(hwaddr.try_into().unwrap(), input_sliced);
|
qemu.write_mem(hwaddr.try_into().unwrap(), input_sliced)?;
|
||||||
}
|
}
|
||||||
#[cfg(emulation_mode = "systemmode")]
|
#[cfg(emulation_mode = "systemmode")]
|
||||||
{
|
unsafe {
|
||||||
qemu.write_phys_mem(hwaddr, input_sliced);
|
qemu.write_phys_mem(hwaddr, input_sliced);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
GuestAddrKind::Virtual(vaddr) => unsafe {
|
GuestAddrKind::Virtual(vaddr) => {
|
||||||
self.cpu
|
self.cpu
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.write_mem(vaddr.try_into().unwrap(), input_sliced);
|
.write_mem(vaddr.try_into().unwrap(), input_sliced)?;
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
input_sliced.len().try_into().unwrap()
|
Ok(input_sliced.len().try_into().unwrap())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1038,16 +1113,16 @@ pub mod pybind {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn write_mem(&self, addr: GuestAddr, buf: &[u8]) {
|
fn write_mem(&self, addr: GuestAddr, buf: &[u8]) {
|
||||||
unsafe {
|
self.qemu
|
||||||
self.qemu.write_mem(addr, buf);
|
.write_mem(addr, buf)
|
||||||
}
|
.expect("Write to memory failed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_mem(&self, addr: GuestAddr, size: usize) -> Vec<u8> {
|
fn read_mem(&self, addr: GuestAddr, size: usize) -> Vec<u8> {
|
||||||
let mut buf = vec![0; size];
|
let mut buf = vec![0; size];
|
||||||
unsafe {
|
self.qemu
|
||||||
self.qemu.read_mem(addr, &mut buf);
|
.read_mem(addr, &mut buf)
|
||||||
}
|
.expect("Read to memory failed.");
|
||||||
buf
|
buf
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,8 +16,8 @@ use libc::EXIT_SUCCESS;
|
|||||||
use num_traits::Zero;
|
use num_traits::Zero;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
FastSnapshotPtr, GuestAddrKind, MemAccessInfo, Qemu, QemuMemoryChunk, QemuSnapshotCheckResult,
|
FastSnapshotPtr, GuestAddrKind, MemAccessInfo, Qemu, QemuMemoryChunk, QemuRWError,
|
||||||
CPU,
|
QemuRWErrorCause, QemuRWErrorKind, QemuSnapshotCheckResult, CPU,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(super) extern "C" fn qemu_cleanup_atexit() {
|
pub(super) extern "C" fn qemu_cleanup_atexit() {
|
||||||
@ -140,38 +140,40 @@ impl CPU {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write a value to a guest address.
|
/// Read a value from a guest address, taking into account the potential MMU / MPU.
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
/// This will write to a translated guest address (using `g2h`).
|
/// no check is done on the correctness of the operation.
|
||||||
/// It just adds `guest_base` and writes to that location, without checking the bounds.
|
/// if a problem occurred during the operation, there will be no feedback
|
||||||
/// This may only be safely used for valid guest addresses!
|
pub unsafe fn read_mem_unchecked(&self, addr: GuestAddr, buf: &mut [u8]) {
|
||||||
pub unsafe fn write_mem(&self, addr: GuestAddr, buf: &[u8]) {
|
|
||||||
// TODO use gdbstub's target_cpu_memory_rw_debug
|
// TODO use gdbstub's target_cpu_memory_rw_debug
|
||||||
libafl_qemu_sys::cpu_memory_rw_debug(
|
unsafe {
|
||||||
self.ptr,
|
libafl_qemu_sys::cpu_memory_rw_debug(
|
||||||
addr as GuestVirtAddr,
|
self.ptr,
|
||||||
buf.as_ptr() as *mut _,
|
addr as GuestVirtAddr,
|
||||||
buf.len(),
|
buf.as_mut_ptr() as *mut _,
|
||||||
true,
|
buf.len(),
|
||||||
);
|
false,
|
||||||
|
)
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read a value from a guest address.
|
/// Write a value to a guest address, taking into account the potential MMU / MPU.
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
/// This will read from a translated guest address (using `g2h`).
|
/// no check is done on the correctness of the operation.
|
||||||
/// It just adds `guest_base` and writes to that location, without checking the bounds.
|
/// if a problem occurred during the operation, there will be no feedback
|
||||||
/// This may only be safely used for valid guest addresses!
|
pub fn write_mem_unchecked(&self, addr: GuestAddr, buf: &[u8]) {
|
||||||
pub unsafe fn read_mem(&self, addr: GuestAddr, buf: &mut [u8]) {
|
|
||||||
// TODO use gdbstub's target_cpu_memory_rw_debug
|
// TODO use gdbstub's target_cpu_memory_rw_debug
|
||||||
libafl_qemu_sys::cpu_memory_rw_debug(
|
unsafe {
|
||||||
self.ptr,
|
libafl_qemu_sys::cpu_memory_rw_debug(
|
||||||
addr as GuestVirtAddr,
|
self.ptr,
|
||||||
buf.as_mut_ptr() as *mut _,
|
addr as GuestVirtAddr,
|
||||||
buf.len(),
|
buf.as_ptr() as *mut _,
|
||||||
false,
|
buf.len(),
|
||||||
);
|
true,
|
||||||
|
)
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,6 +184,12 @@ impl Qemu {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Write a value to a physical guest address, including ROM areas.
|
/// Write a value to a physical guest address, including ROM areas.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// No check is done on the correctness of the operation at the moment.
|
||||||
|
/// Nothing bad will happen if the operation is incorrect, but it will be silently skipped.
|
||||||
|
// TODO: use address_space_rw and check for the result MemTxResult
|
||||||
pub unsafe fn write_phys_mem(&self, paddr: GuestPhysAddr, buf: &[u8]) {
|
pub unsafe fn write_phys_mem(&self, paddr: GuestPhysAddr, buf: &[u8]) {
|
||||||
libafl_qemu_sys::cpu_physical_memory_rw(
|
libafl_qemu_sys::cpu_physical_memory_rw(
|
||||||
paddr,
|
paddr,
|
||||||
@ -191,7 +199,13 @@ impl Qemu {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read a value from a physical guest address.
|
/// Read a value from a physical guest address, including ROM areas.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// No check is done on the correctness of the operation at the moment.
|
||||||
|
/// Nothing bad will happen if the operation is incorrect, but it will be silently skipped.
|
||||||
|
// TODO: use address_space_rw and check for the result MemTxResult
|
||||||
pub unsafe fn read_phys_mem(&self, paddr: GuestPhysAddr, buf: &mut [u8]) {
|
pub unsafe fn read_phys_mem(&self, paddr: GuestPhysAddr, buf: &mut [u8]) {
|
||||||
libafl_qemu_sys::cpu_physical_memory_rw(
|
libafl_qemu_sys::cpu_physical_memory_rw(
|
||||||
paddr,
|
paddr,
|
||||||
|
@ -9,7 +9,7 @@ use libafl_qemu_sys::{
|
|||||||
pageflags_get_root, read_self_maps, GuestAddr, GuestUsize, IntervalTreeNode, IntervalTreeRoot,
|
pageflags_get_root, read_self_maps, GuestAddr, GuestUsize, IntervalTreeNode, IntervalTreeRoot,
|
||||||
MapInfo, MmapPerms, VerifyAccess,
|
MapInfo, MmapPerms, VerifyAccess,
|
||||||
};
|
};
|
||||||
use libc::{c_char, c_int, c_uchar, strlen};
|
use libc::{c_int, c_uchar, strlen};
|
||||||
#[cfg(feature = "python")]
|
#[cfg(feature = "python")]
|
||||||
use pyo3::{pyclass, pymethods, IntoPy, PyObject, PyRef, PyRefMut, Python};
|
use pyo3::{pyclass, pymethods, IntoPy, PyObject, PyRef, PyRefMut, Python};
|
||||||
|
|
||||||
@ -79,27 +79,47 @@ impl Drop for GuestMaps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl CPU {
|
impl CPU {
|
||||||
/// Write a value to a guest address.
|
|
||||||
///
|
|
||||||
/// # Safety
|
|
||||||
/// This will write to a translated guest address (using `g2h`).
|
|
||||||
/// It just adds `guest_base` and writes to that location, without checking the bounds.
|
|
||||||
/// This may only be safely used for valid guest addresses!
|
|
||||||
pub unsafe fn write_mem(&self, addr: GuestAddr, buf: &[u8]) {
|
|
||||||
let host_addr = Qemu::get().unwrap().g2h(addr);
|
|
||||||
copy_nonoverlapping(buf.as_ptr(), host_addr, buf.len());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Read a value from a guest address.
|
/// Read a value from a guest address.
|
||||||
|
/// The input address is not checked for validity.
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
/// This will read from a translated guest address (using `g2h`).
|
/// This will read from a translated guest address (using `g2h`).
|
||||||
/// It just adds `guest_base` and writes to that location, without checking the bounds.
|
/// It just adds `guest_base` and writes to that location, without checking the bounds.
|
||||||
/// This may only be safely used for valid guest addresses!
|
/// This may only be safely used for valid guest addresses!
|
||||||
pub unsafe fn read_mem(&self, addr: GuestAddr, buf: &mut [u8]) {
|
pub unsafe fn read_mem_unchecked(&self, addr: GuestAddr, buf: &mut [u8]) {
|
||||||
let host_addr = Qemu::get().unwrap().g2h(addr);
|
let host_addr = Qemu::get().unwrap().g2h(addr);
|
||||||
copy_nonoverlapping(host_addr, buf.as_mut_ptr(), buf.len());
|
copy_nonoverlapping(host_addr, buf.as_mut_ptr(), buf.len());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Write a value to a guest address.
|
||||||
|
/// The input address in not checked for validity.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
/// This will write to a translated guest address (using `g2h`).
|
||||||
|
/// It just adds `guest_base` and writes to that location, without checking the bounds.
|
||||||
|
/// This may only be safely used for valid guest addresses!
|
||||||
|
pub unsafe fn write_mem_unchecked(&self, addr: GuestAddr, buf: &[u8]) {
|
||||||
|
let host_addr = Qemu::get().unwrap().g2h(addr);
|
||||||
|
copy_nonoverlapping(buf.as_ptr(), host_addr, buf.len());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn g2h<T>(&self, addr: GuestAddr) -> *mut T {
|
||||||
|
unsafe { (addr as usize + guest_base) as *mut T }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn h2g<T>(&self, addr: *const T) -> GuestAddr {
|
||||||
|
unsafe { (addr as usize - guest_base) as GuestAddr }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn access_ok(&self, kind: VerifyAccess, addr: GuestAddr, size: usize) -> bool {
|
||||||
|
unsafe {
|
||||||
|
// TODO add support for tagged GuestAddr
|
||||||
|
libafl_qemu_sys::page_check_range(addr, size as GuestAddr, kind.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::unused_self)]
|
#[allow(clippy::unused_self)]
|
||||||
@ -141,7 +161,7 @@ impl Qemu {
|
|||||||
unsafe {
|
unsafe {
|
||||||
from_utf8_unchecked_mut(from_raw_parts_mut(
|
from_utf8_unchecked_mut(from_raw_parts_mut(
|
||||||
exec_path as *mut c_uchar,
|
exec_path as *mut c_uchar,
|
||||||
strlen(exec_path as *const c_char),
|
strlen(exec_path.cast_const()),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,3 +73,6 @@ libafl_qemu = { path = "../libafl_qemu", version = "0.13.2" }
|
|||||||
[lib]
|
[lib]
|
||||||
name = "libafl_sugar"
|
name = "libafl_sugar"
|
||||||
crate-type = ["cdylib", "rlib"]
|
crate-type = ["cdylib", "rlib"]
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
@ -1,22 +1,6 @@
|
|||||||
//! Sugar API to simplify the life of users of `LibAFL` that just want to fuzz.
|
//! Sugar API to simplify the life of users of `LibAFL` that just want to fuzz.
|
||||||
/*! */
|
/*! */
|
||||||
#![cfg_attr(feature = "document-features", doc = document_features::document_features!())]
|
#![cfg_attr(feature = "document-features", doc = document_features::document_features!())]
|
||||||
#![deny(rustdoc::broken_intra_doc_links)]
|
|
||||||
#![deny(clippy::all)]
|
|
||||||
#![deny(clippy::pedantic)]
|
|
||||||
#![forbid(unexpected_cfgs)]
|
|
||||||
#![allow(
|
|
||||||
clippy::unreadable_literal,
|
|
||||||
clippy::type_repetition_in_bounds,
|
|
||||||
clippy::missing_errors_doc,
|
|
||||||
clippy::cast_possible_truncation,
|
|
||||||
clippy::used_underscore_binding,
|
|
||||||
clippy::ptr_as_ptr,
|
|
||||||
clippy::missing_panics_doc,
|
|
||||||
clippy::missing_docs_in_private_items,
|
|
||||||
clippy::module_name_repetitions,
|
|
||||||
clippy::unreadable_literal
|
|
||||||
)]
|
|
||||||
#![cfg_attr(not(test), warn(
|
#![cfg_attr(not(test), warn(
|
||||||
missing_debug_implementations,
|
missing_debug_implementations,
|
||||||
missing_docs,
|
missing_docs,
|
||||||
|
@ -86,4 +86,6 @@ serde = { workspace = true, default-features = false, features = [
|
|||||||
] } # serialization lib
|
] } # serialization lib
|
||||||
meminterval = { workspace = true, features = ["serde"], optional = true }
|
meminterval = { workspace = true, features = ["serde"], optional = true }
|
||||||
ahash = { workspace = true, default-features = false, optional = true }
|
ahash = { workspace = true, default-features = false, optional = true }
|
||||||
# serde-big-array = "0.3.2"
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
@ -1,24 +1,7 @@
|
|||||||
//! `libafl_targets` contains runtime code, injected in the target itself during compilation.
|
//! `libafl_targets` contains runtime code, injected in the target itself during compilation.
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![deny(rustdoc::broken_intra_doc_links)]
|
|
||||||
#![deny(clippy::all)]
|
|
||||||
#![deny(clippy::pedantic)]
|
|
||||||
#![forbid(unexpected_cfgs)]
|
|
||||||
// For `std::simd`
|
// For `std::simd`
|
||||||
#![cfg_attr(nightly, feature(portable_simd))]
|
#![cfg_attr(nightly, feature(portable_simd))]
|
||||||
#![allow(
|
|
||||||
clippy::unreadable_literal,
|
|
||||||
clippy::type_repetition_in_bounds,
|
|
||||||
clippy::missing_errors_doc,
|
|
||||||
clippy::cast_possible_truncation,
|
|
||||||
clippy::used_underscore_binding,
|
|
||||||
clippy::ptr_as_ptr,
|
|
||||||
clippy::missing_panics_doc,
|
|
||||||
clippy::missing_docs_in_private_items,
|
|
||||||
clippy::module_name_repetitions,
|
|
||||||
clippy::pub_underscore_fields,
|
|
||||||
clippy::into_iter_without_iter, // broken
|
|
||||||
)]
|
|
||||||
#![cfg_attr(not(test), warn(
|
#![cfg_attr(not(test), warn(
|
||||||
missing_debug_implementations,
|
missing_debug_implementations,
|
||||||
missing_docs,
|
missing_docs,
|
||||||
@ -101,6 +84,8 @@ pub mod sanitizer_ifaces {
|
|||||||
#![allow(missing_docs)]
|
#![allow(missing_docs)]
|
||||||
#![allow(missing_debug_implementations)]
|
#![allow(missing_debug_implementations)]
|
||||||
#![allow(unused_qualifications)]
|
#![allow(unused_qualifications)]
|
||||||
|
#![allow(clippy::pub_underscore_fields)]
|
||||||
|
|
||||||
include!(concat!(env!("OUT_DIR"), "/sanitizer_interfaces.rs"));
|
include!(concat!(env!("OUT_DIR"), "/sanitizer_interfaces.rs"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,4 +34,7 @@ tinyinst = { git = "https://github.com/AFLplusplus/tinyinst-rs" }
|
|||||||
log = { workspace = true }
|
log = { workspace = true }
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
cmake = "0.1.51"
|
cmake = { workspace = true }
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
@ -2,25 +2,6 @@
|
|||||||
The tinyinst module for `LibAFL`.
|
The tinyinst module for `LibAFL`.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#![warn(clippy::cargo)]
|
|
||||||
#![deny(clippy::cargo_common_metadata)]
|
|
||||||
#![deny(rustdoc::broken_intra_doc_links)]
|
|
||||||
#![deny(clippy::all)]
|
|
||||||
#![deny(clippy::pedantic)]
|
|
||||||
#![forbid(unexpected_cfgs)]
|
|
||||||
#![allow(
|
|
||||||
clippy::unreadable_literal,
|
|
||||||
clippy::type_repetition_in_bounds,
|
|
||||||
clippy::missing_errors_doc,
|
|
||||||
clippy::cast_possible_truncation,
|
|
||||||
clippy::used_underscore_binding,
|
|
||||||
clippy::ptr_as_ptr,
|
|
||||||
clippy::missing_panics_doc,
|
|
||||||
clippy::missing_docs_in_private_items,
|
|
||||||
clippy::module_name_repetitions,
|
|
||||||
clippy::unreadable_literal,
|
|
||||||
clippy::negative_feature_names
|
|
||||||
)]
|
|
||||||
#![cfg_attr(not(test), warn(
|
#![cfg_attr(not(test), warn(
|
||||||
missing_debug_implementations,
|
missing_debug_implementations,
|
||||||
missing_docs,
|
missing_docs,
|
||||||
@ -60,9 +41,6 @@ The tinyinst module for `LibAFL`.
|
|||||||
while_true
|
while_true
|
||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
// Till they fix this buggy lint in clippy
|
|
||||||
#![allow(clippy::borrow_as_ptr)]
|
|
||||||
#![allow(clippy::borrow_deref_ref)]
|
|
||||||
|
|
||||||
/// Tinyinst executor
|
/// Tinyinst executor
|
||||||
pub mod executor;
|
pub mod executor;
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && pwd)"
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && pwd)"
|
||||||
cd "$SCRIPT_DIR/.." || exit 1
|
cd "$SCRIPT_DIR/.." || exit 1
|
||||||
|
|
||||||
|
CLIPPY_CMD="RUST_BACKTRACE=full cargo +nightly clippy --all --all-features --no-deps --tests --examples --benches -- -Z macro-backtrace"
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
# Function to run Clippy on a single directory
|
# Function to run Clippy on a single directory
|
||||||
run_clippy() {
|
run_clippy() {
|
||||||
@ -10,20 +12,7 @@ run_clippy() {
|
|||||||
echo "Running Clippy on $dir"
|
echo "Running Clippy on $dir"
|
||||||
pushd "$dir" || return 1
|
pushd "$dir" || return 1
|
||||||
|
|
||||||
RUST_BACKTRACE=full cargo +nightly clippy --all --all-features --no-deps --tests --examples --benches -- -Z macro-backtrace \
|
eval "$CLIPPY_CMD"
|
||||||
-D clippy::all \
|
|
||||||
-D clippy::pedantic \
|
|
||||||
-W clippy::similar_names \
|
|
||||||
-A clippy::type_repetition_in_bounds \
|
|
||||||
-A clippy::missing-errors-doc \
|
|
||||||
-A clippy::cast-possible-truncation \
|
|
||||||
-A clippy::used-underscore-binding \
|
|
||||||
-A clippy::ptr-as-ptr \
|
|
||||||
-A clippy::missing-panics-doc \
|
|
||||||
-A clippy::missing-docs-in-private-items \
|
|
||||||
-A clippy::unseparated-literal-suffix \
|
|
||||||
-A clippy::module-name-repetitions \
|
|
||||||
-A clippy::unreadable-literal
|
|
||||||
|
|
||||||
popd || return 1
|
popd || return 1
|
||||||
}
|
}
|
||||||
@ -52,21 +41,7 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# First run it on all
|
# First run it on all
|
||||||
RUST_BACKTRACE=full cargo +nightly clippy --all --all-features --no-deps --tests --examples --benches -- -Z macro-backtrace \
|
eval "$CLIPPY_CMD"
|
||||||
-D clippy::all \
|
|
||||||
-D clippy::pedantic \
|
|
||||||
-W clippy::similar_names \
|
|
||||||
-A clippy::type_repetition_in_bounds \
|
|
||||||
-A clippy::missing-errors-doc \
|
|
||||||
-A clippy::cast-possible-truncation \
|
|
||||||
-A clippy::used-underscore-binding \
|
|
||||||
-A clippy::ptr-as-ptr \
|
|
||||||
-A clippy::missing-panics-doc \
|
|
||||||
-A clippy::missing-docs-in-private-items \
|
|
||||||
-A clippy::unseparated-literal-suffix \
|
|
||||||
-A clippy::module-name-repetitions \
|
|
||||||
-A clippy::unreadable-literal
|
|
||||||
|
|
||||||
|
|
||||||
# Loop through each project and run Clippy
|
# Loop through each project and run Clippy
|
||||||
for project in "${PROJECTS[@]}"; do
|
for project in "${PROJECTS[@]}"; do
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
|
||||||
LIBAFL_DIR=$(realpath "$SCRIPT_DIR/..")
|
|
||||||
|
|
||||||
export LIBAFL_QEMU_GEN_STUBS=1
|
|
||||||
|
|
||||||
cd "${LIBAFL_DIR}/libafl_qemu" || exit 1
|
|
||||||
cargo build
|
|
11
scripts/update_bindings.sh
Executable file
11
scripts/update_bindings.sh
Executable file
@ -0,0 +1,11 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && pwd)"
|
||||||
|
cd "$SCRIPT_DIR/.." || exit 1
|
||||||
|
|
||||||
|
# Update LibAFL QEMU bindings
|
||||||
|
pushd libafl_qemu
|
||||||
|
LIBAFL_QEMU_GEN_STUBS=1 cargo +nightly build || exit 1
|
||||||
|
popd
|
@ -10,5 +10,8 @@ keywords = ["ci"]
|
|||||||
categories = ["development-tools::testing"]
|
categories = ["development-tools::testing"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
cargo_toml = "0.20"
|
cargo_toml = "0.20.5"
|
||||||
walkdir = "2"
|
walkdir = "2.5.0"
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
@ -23,8 +23,11 @@ categories = [
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
log = "0.4.20"
|
log = { workspace = true }
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
name = "deexit"
|
name = "deexit"
|
||||||
crate-type = ["cdylib"]
|
crate-type = ["cdylib"]
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
@ -25,10 +25,12 @@ categories = [
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
libafl = { path = "../../../libafl", default-features = false }
|
libafl = { path = "../../../libafl", default-features = false }
|
||||||
serde_json = "1.0"
|
serde_json = { workspace = true, default-features = true }
|
||||||
regex = "1"
|
regex = { workspace = true }
|
||||||
postcard = { version = "1.0", features = [
|
postcard = { workspace = true, features = [
|
||||||
"alloc",
|
"alloc",
|
||||||
], default-features = false } # no_std compatible serde serialization format
|
], default-features = false } # no_std compatible serde serialization format
|
||||||
clap = { version = "4.5", features = ["derive"] }
|
clap = { workspace = true, features = ["derive"] }
|
||||||
# log = "0.4.20"
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
@ -21,15 +21,21 @@ categories = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
criterion = "0.5" # Benchmarking
|
|
||||||
ahash = { version = "0.8", default-features = false } # The hash function already used in hashbrown
|
|
||||||
rustc-hash = { version = "1.1", default-features = false } # yet another hash
|
|
||||||
xxhash-rust = { version = "0.8.5", features = ["xxh3"] } # xxh3 hashing for rust
|
|
||||||
libafl_bolts = { path = "../../libafl_bolts", default-features = false, features = [
|
libafl_bolts = { path = "../../libafl_bolts", default-features = false, features = [
|
||||||
"xxh3",
|
"xxh3",
|
||||||
"alloc",
|
"alloc",
|
||||||
] } # libafl_bolts
|
] } # libafl_bolts
|
||||||
|
|
||||||
|
criterion = "0.5.1" # Benchmarking
|
||||||
|
ahash = { workspace = true, default-features = false } # The hash function already used in hashbrown
|
||||||
|
rustc-hash = { version = "2.0.0", default-features = false } # yet another hash
|
||||||
|
xxhash-rust = { version = "0.8.12", features = [
|
||||||
|
"xxh3",
|
||||||
|
] } # xxh3 hashing for rust
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
[[bench]]
|
[[bench]]
|
||||||
name = "rand_speeds"
|
name = "rand_speeds"
|
||||||
harness = false
|
harness = false
|
||||||
|
Loading…
x
Reference in New Issue
Block a user