From 60a6c3f68b6057f00c1870ed82ff12462b0eb235 Mon Sep 17 00:00:00 2001 From: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com> Date: Thu, 15 Sep 2022 19:25:56 +0100 Subject: [PATCH] Add support for ARMBE8 (#768) * Changes to build QEMU out-of-tree so that we don't need to clone the repo for each feature combination we build * Add be support to libafl_qemu * More config tweaks Co-authored-by: Your Name --- libafl_qemu/Cargo.toml | 1 + libafl_qemu/build_linux.rs | 45 +++++++++++++++++++++++++++++--------- 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/libafl_qemu/Cargo.toml b/libafl_qemu/Cargo.toml index 8d77ec3c42..4461ebe7b5 100644 --- a/libafl_qemu/Cargo.toml +++ b/libafl_qemu/Cargo.toml @@ -20,6 +20,7 @@ x86_64 = [] # build qemu for x86_64 (default) i386 = [] # build qemu for i386 arm = [] # build qemu for arm aarch64 = [] # build qemu for aarch64 +be = [] usermode = [] diff --git a/libafl_qemu/build_linux.rs b/libafl_qemu/build_linux.rs index 8c53b2d708..f66c56d766 100644 --- a/libafl_qemu/build_linux.rs +++ b/libafl_qemu/build_linux.rs @@ -36,7 +36,12 @@ pub fn build() { // Else, we default to `x86_64` - having a default makes CI easier :) assert_unique_feature!("arm", "aarch64", "i386", "i86_64"); - let cpu_target = if cfg!(feature = "x86_64") { + // Make sure that we don't have BE set for any architecture other than arm + // Sure aarch64 may support BE, but its not in common usage and we don't + // need it yet and so haven't tested it + assert_unique_feature!("be", "aarch64", "i386", "i86_64"); + + let mut cpu_target = if cfg!(feature = "x86_64") { "x86_64".to_string() } else if cfg!(feature = "arm") { "arm".to_string() @@ -63,6 +68,20 @@ pub fn build() { println!("cargo:rustc-cfg=cpu_target=\"{}\"", cpu_target); + // qemu-system-arm supports both big and little endian configurations and so + // therefore the "be" feature should ignored in this configuration. Also + // ignore the feature if we are running in clippy which enables all the + // features at once (disabling the check for mutually exclusive options) + // resulting in cpu_target being set to 'x86_64' above which obviously + // doesn't support BE. + if cfg!(feature = "be") && cfg!(feature = "arm") && cfg!(feature = "usermode") && !cfg!(feature = "clippy"){ + // We have told rustc which CPU target to use above (it doesn't need + // to make any changes for endianness), however, we need QEMU to be + // built for the right endian-ness, so we update the cpu_target for + // here on down + cpu_target += "eb"; + } + if std::env::var("DOCS_RS").is_ok() { return; // only build when we're not generating docs } @@ -85,9 +104,9 @@ pub fn build() { let qemu_path = if let Some(qemu_dir) = custum_qemu_dir.as_ref() { Path::new(&qemu_dir).to_path_buf() } else { - let qemu_path = out_dir_path.join(QEMU_DIRNAME); + let qemu_path = target_dir.join(QEMU_DIRNAME); - let qemu_rev = out_dir_path.join("QEMU_REVISION"); + let qemu_rev = target_dir.join("QEMU_REVISION"); if qemu_rev.exists() && fs::read_to_string(&qemu_rev).expect("Failed to read QEMU_REVISION") != QEMU_REVISION { @@ -139,7 +158,11 @@ pub fn build() { #[cfg(not(feature = "usermode"))] let target_suffix = "softmmu"; - let build_dir = qemu_path.join("build"); + let build_dir = out_dir_path.join("build"); + if !build_dir.is_dir() { + fs::create_dir_all(&build_dir).unwrap(); + } + #[cfg(feature = "usermode")] let output_lib = build_dir.join(&format!("libqemu-{}.so", cpu_target)); #[cfg(not(feature = "usermode"))] @@ -154,9 +177,11 @@ pub fn build() { .arg("distclean") .status(), );*/ + let configure = qemu_path.join("configure"); + #[cfg(feature = "usermode")] - Command::new("./configure") - .current_dir(&qemu_path) + Command::new(configure) + .current_dir(&build_dir) //.arg("--as-static-lib") .arg("--as-shared-lib") .arg(&format!("--target-list={}-{}", cpu_target, target_suffix)) @@ -164,8 +189,8 @@ pub fn build() { .status() .expect("Configure failed"); #[cfg(not(feature = "usermode"))] - Command::new("./configure") - .current_dir(&qemu_path) + Command::new(configure) + .current_dir(&build_dir) //.arg("--as-static-lib") .arg("--as-shared-lib") .arg(&format!("--target-list={}-{}", cpu_target, target_suffix)) @@ -173,14 +198,14 @@ pub fn build() { .expect("Configure failed"); if let Ok(j) = jobs { Command::new("make") - .current_dir(&qemu_path) + .current_dir(&build_dir) .arg("-j") .arg(&j) .status() .expect("Make failed"); } else { Command::new("make") - .current_dir(&qemu_path) + .current_dir(&build_dir) .arg("-j") .status() .expect("Make failed");