QEMU target arch selector via feature flag (#405)

* QEMU target arch selector via feature flag

* fix ci

* fixing ci some mmore

* more ci fixes, defaulting to x86_64 always

* more ci

* i368 -> i386 typo fix

* revert forkserver changes

* trying to fix clippy

* docs

* fixed warnings

* more clippy action

* qemu example arch

* bring back deprecated function I don't know how to replace

* get rid of deprecated feature again'

* builds?i
This commit is contained in:
Dominik Maier 2021-12-06 20:06:47 +01:00 committed by GitHub
parent 0d0fe9eaca
commit 83583a867f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 89 additions and 19 deletions

View File

@ -63,7 +63,7 @@ jobs:
# cargo-hack's --feature-powerset would be nice here but libafl has a too many knobs # cargo-hack's --feature-powerset would be nice here but libafl has a too many knobs
- name: Check each feature - name: Check each feature
# Skipping python as it has to be built with the `maturin` tool # Skipping python as it has to be built with the `maturin` tool
run: cargo hack check --feature-powerset --depth=2 --exclude-features=agpl,nautilus,python,sancov_pcguard_edges --no-dev-deps run: cargo hack check --feature-powerset --depth=2 --exclude-features=agpl,nautilus,python,sancov_pcguard_edges,arm,aarch64,i386 --no-dev-deps
# pcguard edges and pcguard hitcounts are not compatible and we need to build them seperately # pcguard edges and pcguard hitcounts are not compatible and we need to build them seperately
- name: Check pcguard edges - name: Check pcguard edges
run: cargo check --features=sancov_pcguard_edges run: cargo check --features=sancov_pcguard_edges

View File

@ -16,4 +16,4 @@ debug = true
[dependencies] [dependencies]
libafl = { path = "../../libafl/" } libafl = { path = "../../libafl/" }
libafl_qemu = { path = "../../libafl_qemu/" } libafl_qemu = { path = "../../libafl_qemu/", features = ["x86_64"] }

View File

@ -218,7 +218,6 @@ impl InProcessHandlers {
} }
} }
#[must_use]
pub fn new<E, EM, I, OC, OF, OT, S, Z>() -> Result<Self, Error> pub fn new<E, EM, I, OC, OF, OT, S, Z>() -> Result<Self, Error>
where where
I: Input, I: Input,

View File

@ -246,7 +246,7 @@ fn generate_mutations(iter: impl Iterator<Item = (SymExprRef, SymExpr)>) -> Vec<
assert_eq!(bits_to_insert % 8, 0, "can only insert full bytes"); assert_eq!(bits_to_insert % 8, 0, "can only insert full bytes");
let after_len = (u64::from(target.get_size()) / 8) - offset - (bits_to_insert / 8); let after_len = (u64::from(target.get_size()) / 8) - offset - (bits_to_insert / 8);
Some( Some(
std::array::IntoIter::new([ [
if offset == 0 { if offset == 0 {
None None
} else { } else {
@ -267,7 +267,8 @@ fn generate_mutations(iter: impl Iterator<Item = (SymExprRef, SymExpr)>) -> Vec<
false, false,
)) ))
}, },
]) ]
.into_iter()
.reduce(|acc: Option<BV>, val: Option<BV>| match (acc, val) { .reduce(|acc: Option<BV>, val: Option<BV>| match (acc, val) {
(Some(prev), Some(next)) => Some(prev.concat(&next)), (Some(prev), Some(next)) => Some(prev.concat(&next)),
(Some(prev), None) => Some(prev), (Some(prev), None) => Some(prev),

View File

@ -14,6 +14,14 @@ edition = "2021"
python = ["pyo3", "pyo3-build-config"] python = ["pyo3", "pyo3-build-config"]
default = [] default = []
# The following architecture features are mutually exclusive.
x86_64 = [] # build qemu for x86_64 (default)
i386 = [] # build qemu for i386
arm = [] # build qemu for arm
aarch64 = [] # build qemu for aarch64
clippy = [] # special feature for clippy, don't use in normal projects§
[dependencies] [dependencies]
libafl = { path = "../libafl", version = "0.7.0" } libafl = { path = "../libafl", version = "0.7.0" }
libafl_targets = { path = "../libafl_targets", version = "0.7.0" } libafl_targets = { path = "../libafl_targets", version = "0.7.0" }

View File

@ -11,12 +11,24 @@ fn build_dep_check(tools: &[&str]) {
} }
} }
#[macro_export]
macro_rules! assert_unique_feature {
() => {};
($first:tt $(,$rest:tt)*) => {
$(
#[cfg(not(feature = "clippy"))] // ignore multiple definition for clippy
#[cfg(all(feature = $first, feature = $rest))]
compile_error!(concat!("features \"", $first, "\" and \"", $rest, "\" cannot be used together"));
)*
assert_unique_feature!($($rest),*);
}
}
#[allow(clippy::too_many_lines)] #[allow(clippy::too_many_lines)]
fn main() { fn main() {
println!("cargo:rerun-if-changed=build.rs"); println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed=src/asan-giovese.c"); println!("cargo:rerun-if-changed=src/asan-giovese.c");
println!("cargo:rerun-if-changed=src/asan-giovese.h"); println!("cargo:rerun-if-changed=src/asan-giovese.h");
println!("cargo:rerun-if-env-changed=CPU_TARGET");
println!("cargo:rerun-if-env-changed=CROSS_CC"); println!("cargo:rerun-if-env-changed=CROSS_CC");
let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap(); let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap();
@ -24,13 +36,40 @@ fn main() {
return; return;
} }
// Make sure we have at least and at most one architecutre feature set
// Else, we default to `x86_64` - having a default makes CI easier :)
assert_unique_feature!("arm", "aarch64", "i386", "i86_64");
#[cfg(not(any(
feature = "arm",
feature = "aarch64",
feature = "i386",
feature = "x86_64"
)))]
println!(
"cargo:warning=No architecture feature enabled for libafl_qemu, supported: arm, aarch64, i386, x86_64 - defaulting to x86_64"
);
let cpu_target = if cfg!(feature = "clippy") {
// assume x86_64 for clippy
"x86_64"
} else if cfg!(feature = "arm") {
"arm"
} else if cfg!(feature = "aarch64") {
"aarch64"
} else if cfg!(feature = "i386") {
"368"
} else {
// if cfg!(feature = "x86_64") {
"x86_64"
/*} else {
panic!("No architecture feture enabled for libafl_qemu");
*/
};
let jobs = env::var("CARGO_BUILD_JOBS"); let jobs = env::var("CARGO_BUILD_JOBS");
let cpu_target = env::var("CPU_TARGET").unwrap_or_else(|_| {
println!("cargo:warning=CPU_TARGET is not set, default to x86_64");
"x86_64".to_owned()
});
let cross_cc = env::var("CROSS_CC").unwrap_or_else(|_| { let cross_cc = env::var("CROSS_CC").unwrap_or_else(|_| {
println!("cargo:warning=CROSS_CC is not set, default to cc (things can go wrong if CPU_TARGET is not the host arch)"); println!("cargo:warning=CROSS_CC is not set, default to cc (things can go wrong if the selected cpu target ({}) is not the host arch ({}))", cpu_target, env::consts::ARCH);
"cc".to_owned() "cc".to_owned()
}); });

View File

@ -1,17 +1,40 @@
use std::env; use std::env;
#[cfg(feature = "aarch64")]
pub mod aarch64; pub mod aarch64;
pub mod arm; #[cfg(all(feature = "aarch64", not(feature = "clippy")))]
pub mod i386;
pub mod x86_64;
#[cfg(cpu_target = "aarch64")]
pub use aarch64::*; pub use aarch64::*;
#[cfg(cpu_target = "arm")]
#[cfg(feature = "arm")]
pub mod arm;
#[cfg(all(feature = "arm", not(feature = "clippy")))]
pub use arm::*; pub use arm::*;
#[cfg(cpu_target = "i386")]
#[cfg(feature = "i386")]
pub mod i386;
#[cfg(all(feature = "i386", not(feature = "clippy")))]
pub use i386::*; pub use i386::*;
#[cfg(cpu_target = "x86_64")]
// We default to x86_64, having a default makes CI easier :)
#[cfg(any(
feature = "x86_64",
not(any(
feature = "arm",
feature = "aarch64",
feature = "i386",
feature = "x86_64"
))
))]
pub mod x86_64;
#[cfg(any(
feature = "x86_64",
not(any(
feature = "arm",
feature = "aarch64",
feature = "i386",
feature = "x86_64"
))
))]
pub use x86_64::*; pub use x86_64::*;
pub mod elf; pub mod elf;