Hexagon support (#1323)

* Hexagon support

* Fix format

* Fix needless bool

* Address comments

---------

Co-authored-by: Andrea Fioraldi <andreafioraldi@gmail.com>
This commit is contained in:
Ivan Fratric 2023-07-04 11:08:36 +02:00 committed by GitHub
parent 07f4c42ecf
commit 829b5049e6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 104 additions and 12 deletions

View File

@ -12,9 +12,10 @@ edition = "2021"
categories = ["development-tools::testing", "emulators", "embedded", "os", "no-std"]
[features]
default = ["fork"]
default = ["fork", "build_libqasan"]
python = ["pyo3", "pyo3-build-config"]
fork = ["libafl/fork"]
build_libqasan = []
# The following architecture features are mutually exclusive.
x86_64 = ["libafl_qemu_sys/x86_64"] # build qemu for x86_64 (default)
@ -23,6 +24,7 @@ arm = ["libafl_qemu_sys/arm"] # build qemu for arm
aarch64 = ["libafl_qemu_sys/aarch64"] # build qemu for aarch64
mips = ["libafl_qemu_sys/mips"] # build qemu for mips (el, use with the 'be' feature of mips be)
ppc = ["libafl_qemu_sys/ppc"] # build qemu for powerpc
hexagon = ["libafl_qemu_sys/hexagon"] # build qemu for hexagon
be = ["libafl_qemu_sys/be"]

View File

@ -12,6 +12,9 @@ pub fn build() {
"usermode".to_string()
})
};
let build_libqasan = cfg!(all(feature = "build_libqasan", not(feature = "hexagon")));
println!("cargo:rustc-cfg=emulation_mode=\"{emulation_mode}\"");
println!("cargo:rerun-if-env-changed=EMULATION_MODE");
@ -30,6 +33,8 @@ pub fn build() {
"mips".to_string()
} else if cfg!(feature = "ppc") {
"ppc".to_string()
} else if cfg!(feature = "hexagon") {
"hexagon".to_string()
} else {
env::var("CPU_TARGET").unwrap_or_else(|_| {
"x86_64".to_string()
@ -38,7 +43,7 @@ pub fn build() {
println!("cargo:rerun-if-env-changed=CPU_TARGET");
println!("cargo:rustc-cfg=cpu_target=\"{cpu_target}\"");
let cross_cc = if emulation_mode == "usermode" {
let cross_cc = if (emulation_mode == "usermode") && build_libqasan {
// TODO try to autodetect a cross compiler with the arch name (e.g. aarch64-linux-gnu-gcc)
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 the selected cpu target ({cpu_target}) is not the host arch ({}))", env::consts::ARCH);
@ -62,7 +67,7 @@ pub fn build() {
target_dir.pop();
target_dir.pop();
if emulation_mode == "usermode" {
if (emulation_mode == "usermode") && build_libqasan {
let qasan_dir = Path::new("libqasan");
let qasan_dir = fs::canonicalize(qasan_dir).unwrap();

View File

@ -8,7 +8,7 @@ use which::which;
const QEMU_URL: &str = "https://github.com/AFLplusplus/qemu-libafl-bridge";
const QEMU_DIRNAME: &str = "qemu-libafl-bridge";
const QEMU_REVISION: &str = "9302a3a8174a45a14c77be316126f2673248be51";
const QEMU_REVISION: &str = "98efc72c4ca20b60c80dd16e2c88af114b8b2ae7";
fn build_dep_check(tools: &[&str]) {
for tool in tools {

View File

@ -19,6 +19,7 @@ arm = [] # build qemu for arm
aarch64 = [] # build qemu for aarch64
mips = [] # build qemu for mips (el, use with the 'be' feature of mips be)
ppc = [] # build qemu for powerpc
hexagon = [] # build qemu for hexagon
be = []

View File

@ -38,12 +38,12 @@ pub fn build() {
// Make sure we have 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", "mips", "ppc");
assert_unique_feature!("arm", "aarch64", "i386", "i86_64", "mips", "ppc", "hexagon");
// Make sure that we don't have BE set for any architecture other than arm and mips
// 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");
assert_unique_feature!("be", "aarch64", "i386", "i86_64", "hexagon");
let cpu_target = if cfg!(feature = "x86_64") {
"x86_64".to_string()
@ -57,6 +57,8 @@ pub fn build() {
"mips".to_string()
} else if cfg!(feature = "ppc") {
"ppc".to_string()
} else if cfg!(feature = "hexagon") {
"hexagon".to_string()
} else {
env::var("CPU_TARGET").unwrap_or_else(|_| {
println!(

View File

@ -281,6 +281,13 @@ where
ret_addr
};
#[cfg(cpu_target = "hexagon")]
let ret_addr = {
let emu = hooks.emulator();
let ret_addr: GuestAddr = emu.read_reg(Regs::Lr).unwrap();
ret_addr
};
// log::info!("RET @ 0x{:#x}", ret_addr);
let mut collectors = if let Some(h) = hooks.helpers_mut().match_first_type_mut::<Self>() {

View File

@ -0,0 +1,68 @@
use num_enum::{IntoPrimitive, TryFromPrimitive};
#[cfg(feature = "python")]
use pyo3::prelude::*;
pub use strum_macros::EnumIter;
#[derive(IntoPrimitive, TryFromPrimitive, Debug, Clone, Copy, EnumIter)]
#[repr(i32)]
pub enum Regs {
R0 = 0,
R1 = 1,
R2 = 2,
R3 = 3,
R4 = 4,
R5 = 5,
R6 = 6,
R7 = 7,
R8 = 8,
R9 = 9,
R10 = 10,
R11 = 11,
R12 = 12,
R13 = 13,
R14 = 14,
R15 = 15,
R16 = 16,
R17 = 17,
R18 = 18,
R19 = 19,
R20 = 20,
R21 = 21,
R22 = 22,
R23 = 23,
R24 = 24,
R25 = 25,
R26 = 26,
R27 = 27,
R28 = 28,
R29 = 29,
R30 = 30,
R31 = 31,
Sa0 = 32,
Lc0 = 33,
Sa1 = 34,
Lc1 = 35,
P3_0 = 36,
M0 = 38,
M1 = 39,
Usr = 40,
Pc = 41,
Ugp = 42,
Gp = 43,
Cs0 = 44,
Cs1 = 45,
UpcycleLo = 46,
UpcycleHi = 47,
Framelimit = 48,
Framekey = 49,
Pktcntlo = 50,
Pktcnthi = 51,
}
/// alias registers
#[allow(non_upper_case_globals)]
impl Regs {
pub const Sp: Regs = Regs::R29;
pub const Fp: Regs = Regs::R30;
pub const Lr: Regs = Regs::R31;
}

View File

@ -55,6 +55,11 @@ pub mod ppc;
#[cfg(cpu_target = "ppc")]
pub use ppc::*;
#[cfg(cpu_target = "hexagon")]
pub mod hexagon;
#[cfg(cpu_target = "hexagon")]
pub use hexagon::*;
pub mod elf;
pub mod helper;
@ -65,22 +70,24 @@ pub use hooks::*;
pub mod edges;
pub use edges::QemuEdgeCoverageHelper;
#[cfg(not(cpu_target = "mips"))]
#[cfg(not(any(cpu_target = "mips", cpu_target = "hexagon")))]
pub mod cmplog;
#[cfg(not(cpu_target = "mips"))]
#[cfg(not(any(cpu_target = "mips", cpu_target = "hexagon")))]
pub use cmplog::QemuCmpLogHelper;
#[cfg(emulation_mode = "usermode")]
#[cfg(all(emulation_mode = "usermode", not(cpu_target = "hexagon")))]
pub mod snapshot;
#[cfg(emulation_mode = "usermode")]
#[cfg(all(emulation_mode = "usermode", not(cpu_target = "hexagon")))]
pub use snapshot::QemuSnapshotHelper;
#[cfg(emulation_mode = "usermode")]
#[cfg(all(emulation_mode = "usermode", not(cpu_target = "hexagon")))]
pub mod asan;
#[cfg(emulation_mode = "usermode")]
#[cfg(all(emulation_mode = "usermode", not(cpu_target = "hexagon")))]
pub use asan::{init_with_asan, QemuAsanHelper};
#[cfg(not(cpu_target = "hexagon"))]
pub mod calls;
#[cfg(not(cpu_target = "hexagon"))]
pub mod drcov;
pub mod executor;