From 32eec2d788bc99cf56c4fba9729a85306a79e7c0 Mon Sep 17 00:00:00 2001 From: morecoding2 Date: Sun, 30 Jun 2024 22:45:50 +0200 Subject: [PATCH] Add trace observer/feedback + Rocket and Spike support --- fuzzers/chipyard-vcs-fuzzer/Cargo.toml | 1 + .../chipyard-vcs-fuzzer/src/differential.rs | 290 ---------------- .../src/differential_feedback.rs | 113 ------- fuzzers/chipyard-vcs-fuzzer/src/main.rs | 39 +-- fuzzers/chipyard-vcs-fuzzer/src/simv.rs | 41 +++ .../chipyard-vcs-fuzzer/src/trace_observer.rs | 91 +++++ .../src/differential_feedback.rs | 89 +++++ libpresifuzz_feedbacks/src/lib.rs | 1 + libpresifuzz_observers/Cargo.toml | 1 + libpresifuzz_observers/spike.log | 313 ++++++++++++++++++ libpresifuzz_observers/src/lib.rs | 2 +- libpresifuzz_observers/src/trace_observer.rs | 235 +++++++++++++ libpresifuzz_observers/src/verdi_observer.rs | 2 +- .../src/verdi_xml_observer.rs | 6 +- 14 files changed, 788 insertions(+), 436 deletions(-) delete mode 100644 fuzzers/chipyard-vcs-fuzzer/src/differential.rs delete mode 100644 fuzzers/chipyard-vcs-fuzzer/src/differential_feedback.rs create mode 100644 fuzzers/chipyard-vcs-fuzzer/src/trace_observer.rs create mode 100644 libpresifuzz_feedbacks/src/differential_feedback.rs create mode 100644 libpresifuzz_observers/spike.log create mode 100644 libpresifuzz_observers/src/trace_observer.rs diff --git a/fuzzers/chipyard-vcs-fuzzer/Cargo.toml b/fuzzers/chipyard-vcs-fuzzer/Cargo.toml index 2febae8..f0b9f1c 100644 --- a/fuzzers/chipyard-vcs-fuzzer/Cargo.toml +++ b/fuzzers/chipyard-vcs-fuzzer/Cargo.toml @@ -38,6 +38,7 @@ clap = { version = "3.2", features = ["default"] } fs_extra = "1.2.0" wait-timeout = "0.1.5" color-print = "0.3.6" +regex = "1" [features] debug = [] \ No newline at end of file diff --git a/fuzzers/chipyard-vcs-fuzzer/src/differential.rs b/fuzzers/chipyard-vcs-fuzzer/src/differential.rs deleted file mode 100644 index 011c3ac..0000000 --- a/fuzzers/chipyard-vcs-fuzzer/src/differential.rs +++ /dev/null @@ -1,290 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Intel Corporation -// -// SPDX-License-Identifier: Apache-2.0 -#![cfg_attr( - test, - deny( - dead_code, - unreachable_code - ) -)] -#![allow(dead_code, unreachable_code)] -//! Executor for differential fuzzing. -//! It wraps two executors that will be run after each other with the same input. -//! In comparison to the [`crate::executors::CombinedExecutor`] it also runs the secondary executor in `run_target`. -//! -use std::{cell::UnsafeCell, fmt::Debug}; - -use libafl_bolts::{ownedref::OwnedMutPtr, tuples::MatchName}; -use serde::{Deserialize, Serialize}; - -use libafl::{ - executors::{Executor, ExitKind, HasObservers}, - inputs::UsesInput, - observers::{DifferentialObserversTuple, ObserversTuple, UsesObservers}, - state::UsesState, - Error, -}; -#[cfg(feature = "debug")] -use color_print::cprintln; - -/// A [`DiffExecutor`] wraps a primary executor, forwarding its methods, and a secondary one -#[derive(Debug)] -pub struct DiffExecutor { - primary: A, - secondary: B, - observers: UnsafeCell>, -} - -impl DiffExecutor { - /// Create a new `DiffExecutor`, wrapping the given `executor`s. - pub fn new(primary: A, secondary: B, observers: DOT) -> Self - where - A: UsesState + HasObservers, - B: UsesState + HasObservers, - DOT: DifferentialObserversTuple, - OTA: ObserversTuple, - OTB: ObserversTuple, - { - Self { - primary, - secondary, - observers: UnsafeCell::new(ProxyObserversTuple { - primary: OwnedMutPtr::Ptr(core::ptr::null_mut()), - secondary: OwnedMutPtr::Ptr(core::ptr::null_mut()), - differential: observers, - }), - } - } - - /// Retrieve the primary `Executor` that is wrapped by this `DiffExecutor`. - pub fn primary(&mut self) -> &mut A { - &mut self.primary - } - - /// Retrieve the secondary `Executor` that is wrapped by this `DiffExecutor`. - pub fn secondary(&mut self) -> &mut B { - &mut self.secondary - } -} - -impl Executor for DiffExecutor -where - A: Executor + HasObservers, - B: Executor + HasObservers, - EM: UsesState, - DOT: DifferentialObserversTuple, - Z: UsesState, -{ - fn run_target( - &mut self, - fuzzer: &mut Z, - state: &mut Self::State, - mgr: &mut EM, - input: &Self::Input, - ) -> Result { - self.observers(); // update in advance - let observers = self.observers.get_mut(); - observers - .differential - .pre_observe_first_all(observers.primary.as_mut())?; - observers.primary.as_mut().pre_exec_all(state, input)?; - let ret1 = self.primary.run_target(fuzzer, state, mgr, input)?; - - if ret1 != ExitKind::Ok && ret1 != ExitKind::Timeout { - #[cfg(feature = "debug")] - cprintln!("[WARNING] First executor did not return success {:?}, skipping testcase!", ret1); - - return Ok(ExitKind::Ok); - } - - self.primary.post_run_reset(); - observers - .primary - .as_mut() - .post_exec_all(state, input, &ret1)?; - observers - .differential - .post_observe_first_all(observers.primary.as_mut())?; - observers - .differential - .pre_observe_second_all(observers.secondary.as_mut())?; - observers.secondary.as_mut().pre_exec_all(state, input)?; - - let ret2 = self.secondary.run_target(fuzzer, state, mgr, input)?; - - self.secondary.post_run_reset(); - observers - .secondary - .as_mut() - .post_exec_all(state, input, &ret2)?; - observers - .differential - .post_observe_second_all(observers.secondary.as_mut())?; - - if ret1 == ret2 { - Ok(ret1) - } else { - // We found a diff in the exit codes! - Ok(ExitKind::Diff { - primary: ret1.into(), - secondary: ret2.into(), - }) - } - } -} - -/// Proxy the observers of the inner executors -#[derive(Serialize, Deserialize, Debug)] -#[serde( - bound = "A: serde::Serialize + serde::de::DeserializeOwned, B: serde::Serialize + serde::de::DeserializeOwned, DOT: serde::Serialize + serde::de::DeserializeOwned" -)] -pub struct ProxyObserversTuple { - primary: OwnedMutPtr, - secondary: OwnedMutPtr, - differential: DOT, -} - -impl ObserversTuple for ProxyObserversTuple -where - A: ObserversTuple, - B: ObserversTuple, - DOT: DifferentialObserversTuple, - S: UsesInput, -{ - fn pre_exec_all(&mut self, state: &mut S, input: &S::Input) -> Result<(), Error> { - self.differential.pre_exec_all(state, input) - } - - fn post_exec_all( - &mut self, - state: &mut S, - input: &S::Input, - exit_kind: &ExitKind, - ) -> Result<(), Error> { - self.differential.post_exec_all(state, input, exit_kind) - } - - fn pre_exec_child_all(&mut self, state: &mut S, input: &S::Input) -> Result<(), Error> { - self.differential.pre_exec_child_all(state, input) - } - - fn post_exec_child_all( - &mut self, - state: &mut S, - input: &S::Input, - exit_kind: &ExitKind, - ) -> Result<(), Error> { - self.differential - .post_exec_child_all(state, input, exit_kind) - } - - /// Returns true if a `stdout` observer was added to the list - #[inline] - fn observes_stdout(&self) -> bool { - self.primary.as_ref().observes_stdout() || self.secondary.as_ref().observes_stdout() - } - /// Returns true if a `stderr` observer was added to the list - #[inline] - fn observes_stderr(&self) -> bool { - self.primary.as_ref().observes_stderr() || self.secondary.as_ref().observes_stderr() - } - - /// Runs `observe_stdout` for all stdout observers in the list - fn observe_stdout(&mut self, stdout: &[u8]) { - self.primary.as_mut().observe_stderr(stdout); - self.secondary.as_mut().observe_stderr(stdout); - } - - /// Runs `observe_stderr` for all stderr observers in the list - fn observe_stderr(&mut self, stderr: &[u8]) { - self.primary.as_mut().observe_stderr(stderr); - self.secondary.as_mut().observe_stderr(stderr); - } -} - -impl MatchName for ProxyObserversTuple -where - A: MatchName, - B: MatchName, - DOT: MatchName, -{ - fn match_name(&self, name: &str) -> Option<&T> { - if let Some(t) = self.primary.as_ref().match_name::(name) { - Some(t) - } else if let Some(t) = self.secondary.as_ref().match_name::(name) { - Some(t) - } else { - self.differential.match_name::(name) - } - } - fn match_name_mut(&mut self, name: &str) -> Option<&mut T> { - if let Some(t) = self.primary.as_mut().match_name_mut::(name) { - Some(t) - } else if let Some(t) = self.secondary.as_mut().match_name_mut::(name) { - Some(t) - } else { - self.differential.match_name_mut::(name) - } - } -} - -impl ProxyObserversTuple { - fn set(&mut self, primary: &A, secondary: &B) { - self.primary = OwnedMutPtr::Ptr(primary as *const A as *mut A); - self.secondary = OwnedMutPtr::Ptr(secondary as *const B as *mut B); - } -} - -impl UsesObservers for DiffExecutor -where - A: HasObservers, - B: HasObservers, - OTA: ObserversTuple, - OTB: ObserversTuple, - DOT: DifferentialObserversTuple, -{ - type Observers = ProxyObserversTuple; -} - -impl UsesState for DiffExecutor -where - A: UsesState, - B: UsesState, -{ - type State = A::State; -} - -impl HasObservers for DiffExecutor -where - A: HasObservers, - B: HasObservers, - OTA: ObserversTuple, - OTB: ObserversTuple, - DOT: DifferentialObserversTuple, -{ - #[inline] - fn observers(&self) -> &ProxyObserversTuple { - unsafe { - self.observers - .get() - .as_mut() - .unwrap() - .set(self.primary.observers(), self.secondary.observers()); - // .set(self.primary.observers(), self.secondary.observers()); - self.observers.get().as_ref().unwrap() - } - } - - #[inline] - fn observers_mut(&mut self) -> &mut ProxyObserversTuple { - unsafe { - self.observers - .get() - .as_mut() - .unwrap() - .set(self.primary.observers(), self.secondary.observers()); - self.observers.get().as_mut().unwrap() - } - } -} diff --git a/fuzzers/chipyard-vcs-fuzzer/src/differential_feedback.rs b/fuzzers/chipyard-vcs-fuzzer/src/differential_feedback.rs deleted file mode 100644 index 93e8c03..0000000 --- a/fuzzers/chipyard-vcs-fuzzer/src/differential_feedback.rs +++ /dev/null @@ -1,113 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Intel Corporation -// -// SPDX-License-Identifier: Apache-2.0 -#![cfg_attr( - test, - deny( - dead_code, - unreachable_code - ) -)] -#![allow(dead_code, unreachable_code, unused_variables, unused_mut)] - -use core::fmt::Debug; -use libafl_bolts::Named; -use libafl::{ - corpus::Testcase, - events::EventFirer, - executors::ExitKind, - feedbacks::Feedback, - inputs::{UsesInput}, - observers::ObserversTuple, - state::State, - Error, -}; -use serde::{Deserialize, Serialize}; -use std::str; -extern crate fs_extra; - -#[cfg(feature = "debug")] -use color_print::cprintln; - -use std::fmt::Write; -use std::{ - fs, -}; - -/// Nop feedback that annotates execution time in the new testcase, if any -/// for this Feedback, the testcase is never interesting (use with an OR). -/// It decides, if the given [`TimeObserver`] value of a run is interesting. -#[derive(Serialize, Deserialize, Clone, Debug)] -pub struct DifferentialFeedback { - first_name: String, - name: String, - counter: u32, -} - -impl Feedback for DifferentialFeedback -where - S: UsesInput + State -{ - #[allow(clippy::wrong_self_convention)] - #[allow(dead_code)] - fn is_interesting( - &mut self, - _state: &mut S, - _manager: &mut EM, - _input: &S::Input, - observers: &OT, - _exit_kind: &ExitKind, - ) -> Result - where - EM: EventFirer, - OT: ObserversTuple, - { - - #[cfg(feature = "debug")] - cprintln!("[WARNING] Skipping trace comparison feedback because it is not implemented for Rocketchip ..."); - return Ok(false); - - //TODO: implement differential testing for Spike - } - - #[inline] - fn append_metadata( - &mut self, - _state: &mut S, - _observers: &OT, - _testcase: &mut Testcase, - ) -> Result<(), Error> - where - OT: ObserversTuple - { - Ok(()) - } - - /// Discard the stored metadata in case that the testcase is not added to the corpus - #[inline] - fn discard_metadata(&mut self, _state: &mut S, _input: &S::Input) -> Result<(), Error> { - Ok(()) - } -} - -impl Named for DifferentialFeedback { - #[inline] - fn name(&self) -> &str { - self.name.as_str() - } -} - -impl DifferentialFeedback { - /// Creates a new [`DifferentialFeedback`], deciding if the given [`VerdiObserver`] value of a run is interesting. - #[must_use] - pub fn new_with_observer( - name: &'static str, - first_name: &'static str, - ) -> Self { - Self { - first_name: first_name.to_string(), - name: name.to_string(), - counter: 0, - } - } -} diff --git a/fuzzers/chipyard-vcs-fuzzer/src/main.rs b/fuzzers/chipyard-vcs-fuzzer/src/main.rs index e7a678c..434bd27 100644 --- a/fuzzers/chipyard-vcs-fuzzer/src/main.rs +++ b/fuzzers/chipyard-vcs-fuzzer/src/main.rs @@ -63,13 +63,20 @@ use std::env; use std::rc::Rc; use libpresifuzz_feedbacks::verdi_feedback::VerdiFeedback; +use libpresifuzz_feedbacks::differential_feedback::DifferentialFeedback; + use libpresifuzz_observers::verdi_observer::VerdiShMapObserver; use libpresifuzz_observers::verdi_observer::VerdiCoverageMetric; +use libpresifuzz_observers::trace_observer::ExecTrace; +use libpresifuzz_observers::trace_observer::SpikeExecTrace; pub mod simv; use crate::simv::SimvCommandConfigurator; +pub mod trace_observer; +use crate::trace_observer::{RocketExecTrace, BoomExecTrace, CVA6ExecTrace}; + use libpresifuzz_mutators::riscv_isa::riscv_mutations; use libpresifuzz_mutators::scheduled::StdISAScheduledMutator; @@ -77,9 +84,6 @@ use libpresifuzz_ec::llmp::Launcher; use libpresifuzz_stages::sync::SyncFromDiskStage; use libpresifuzz_feedbacks::transferred::TransferredFeedback; -mod differential_feedback; -mod differential; - #[derive(Debug)] pub struct WorkDir(Option); @@ -192,27 +196,6 @@ pub fn fuzz() { (feedback, verdi_observer) }; - // FSM seems buggy, disable - //const FSM_MAP_SIZE: usize = (??.0/8.0).ceil() as usize; - // let mut shmem = shmem_provider_client.new_shmem(MAP_SIZE).unwrap(); - // let shmem_buf = shmem.as_mut_slice(); - // let shmem_ptr = shmem_buf.as_mut_ptr() as *mut u32; - // let (verdi_feedback_fsm, verdi_observer_fsm) = { - // let verdi_observer = unsafe { - // VerdiShMapObserver::<{ MAP_SIZE / 4 }>::from_mut_ptr( - // "verdi_fsm", - // workdir, - // shmem_ptr, - // &VerdiCoverageMetric::FSM, - // &"TestDriver.testHarness.chiptop0".to_string() - // ) - // }; - - // let feedback = VerdiFeedback::<{MAP_SIZE/4}>::new_with_observer("verdi_fsm", MAP_SIZE, workdir); - - // (feedback, verdi_observer) - // }; - // 79757 cond coverable // 79757/8=9969 const COND_MAP_SIZE: usize = 9969+8; @@ -275,7 +258,11 @@ pub fn fuzz() { (feedback, verdi_observer) }; - let mut feedback = feedback_or!(verdi_feedback_line, verdi_feedback_tgl, verdi_feedback_branch, verdi_feedback_condition); + let spike_trace_observer = ExecTrace::::new("spike_trace", workdir); + let rocket_trace_observer = ExecTrace::::new("rocket_trace", workdir); + let differential_feedback = DifferentialFeedback::::new("spike_trace", "rocket_trace"); + + let mut feedback = feedback_or!(verdi_feedback_line, verdi_feedback_tgl, verdi_feedback_branch, verdi_feedback_condition, differential_feedback); //verdi_feedback_fsm, let mut objective = (); @@ -299,7 +286,7 @@ pub fn fuzz() { // Finally, instantiate the fuzzer let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective); - let mut executor = simv.into_executor(tuple_list!(verdi_observer_line, verdi_observer_tgl, verdi_observer_branch, verdi_observer_condition)); + let mut executor = simv.into_executor(tuple_list!(verdi_observer_line, verdi_observer_tgl, verdi_observer_branch, verdi_observer_condition, spike_trace_observer, rocket_trace_observer)); //verdi_observer_fsm, #[cfg(feature = "debug")] println!("corpus_dir: {}", corpus_dir.to_string()); diff --git a/fuzzers/chipyard-vcs-fuzzer/src/simv.rs b/fuzzers/chipyard-vcs-fuzzer/src/simv.rs index acb1062..b1ef512 100644 --- a/fuzzers/chipyard-vcs-fuzzer/src/simv.rs +++ b/fuzzers/chipyard-vcs-fuzzer/src/simv.rs @@ -24,6 +24,7 @@ use std::assert; use std::path::Path; use std::process::{Child, Command}; use std::os::unix::fs; +use wait_timeout::ChildExt; use std::time::Duration; use std::env; use std::process::Stdio; @@ -57,6 +58,44 @@ fn copy_dir_all(src: impl AsRef, dst: impl AsRef) -> std::io::Result Ok(()) } +fn exec_spike() -> Result<(), Error> { + let forged_cmd_args = format!("--log-commits ./testcase.elf"); + + let args_vec: Vec<&str> = forged_cmd_args.split(' ').collect(); + + let spike_execution_log = File::create("spike.log").expect("Failed to spike.log"); + let spike_execution_err = File::create("spike.err").expect("Failed to spike.err"); + + // 3. spawn simv + let cmd = Command::new("spike") + .args(&args_vec) + .stdin(Stdio::null()) + .stdout(spike_execution_log) + .stderr(spike_execution_err) + .spawn(); + + match cmd { + Ok(mut child) => { + let timeout = Duration::from_millis(100); + + match child.wait_timeout(timeout) { + Ok(Some(status)) => { + #[cfg(feature = "debug")] + println!("Exited with status {}", status); + } + Ok(None) => { + let _ = child.kill(); + #[cfg(feature = "debug")] + println!("timeout, process is still alive"); + }, + Err(e) => println!("Error waiting: {}", e), + } + } + Err(err) => println!("Process did not even start: {}", err), + }; + Ok(()) +} + #[derive(Clone, Debug)] pub struct SimvCommandConfigurator<'a> { @@ -153,6 +192,8 @@ impl<'a> CommandConfigurator for SimvCommandConfigurator<'a> { println!("Executing command: ./simv-chipyard.harness-RocketConfig {:?}", args_v); } + let exec_spike = exec_spike().expect("Runing Spike failed."); + let hw_execution_log = File::create("terminal.log").expect("Failed to terminal.log"); let hw_execution_err = File::create("terminal.err").expect("Failed to terminal.err"); diff --git a/fuzzers/chipyard-vcs-fuzzer/src/trace_observer.rs b/fuzzers/chipyard-vcs-fuzzer/src/trace_observer.rs new file mode 100644 index 0000000..4b78c51 --- /dev/null +++ b/fuzzers/chipyard-vcs-fuzzer/src/trace_observer.rs @@ -0,0 +1,91 @@ +// SPDX-FileCopyrightText: 2022 Intel Corporation +// +// SPDX-License-Identifier: Apache-2.0 + +use libafl::{ + executors::{ExitKind}, + observers::{Observer}, + Error, + inputs::{UsesInput}, +}; + +use core::{fmt::Debug}; +use serde::{Deserialize, Serialize}; +use libafl_bolts::{HasLen, Named}; + +use std::fs::File; + +extern crate fs_extra; +use std::{str}; +use regex::Regex; +use std::io::{self, BufRead}; + +use libpresifuzz_observers::trace_observer::{ExecTraceParser, TraceLog, OpLog, RegOp, OpType}; + + +#[derive(Copy, Clone, Serialize, Deserialize, Debug)] +pub struct RocketExecTrace; + +impl ExecTraceParser for RocketExecTrace +{ + fn new() -> Self { + RocketExecTrace {} + } + fn parse(&self, workdir: &str) -> Result, Error> { + let mut trace = Vec::::new(); + + let rocket_trace_file = format!("{}/terminal.err", workdir); + + let file = File::open(rocket_trace_file).expect("Unable to open rocket trace file"); + let reader = io::BufReader::new(file); + + let rocket_re = Regex::new(r"C0:\s+\d+ \[\d+\] pc=\[(\w+)\] W\[r ?(\d+)=(\w+)\]\[\d+\] R\[r ?(\d+)=(\w+)\] R\[r ?(\d+)=(\w+)\] inst=\[(\w+)\]").unwrap(); + + for line in reader.lines() { + if let Ok(log_line) = &line { + if let Some(caps) = rocket_re.captures(log_line) { + let ops = vec![ + OpLog::RegOp(RegOp{op_type: OpType::Write, name: caps[2].to_string(), value: u64::from_str_radix(&caps[3], 16).unwrap()}), + OpLog::RegOp(RegOp{op_type: OpType::Read, name: caps[4].to_string(), value: u64::from_str_radix(&caps[5], 16).unwrap()}), + OpLog::RegOp(RegOp{op_type: OpType::Read, name: caps[6].to_string(), value: u64::from_str_radix(&caps[7], 16).unwrap()}) + ]; + + trace.push(TraceLog { + pc: u64::from_str_radix(&caps[1], 16).unwrap(), + inst: u64::from_str_radix(&caps[8], 16).unwrap(), + ops, + }); + } + } + } + Ok(trace) + } +} + +pub struct BoomExecTrace; + +impl ExecTraceParser for BoomExecTrace +{ + fn new() -> Self { + BoomExecTrace {} + } + fn parse(&self, workdir: &str) -> Result, Error> { + let mut trace = Vec::::new(); + // TODO + Ok(trace) + } +} + +pub struct CVA6ExecTrace; + +impl ExecTraceParser for CVA6ExecTrace +{ + fn new() -> Self { + CVA6ExecTrace {} + } + fn parse(&self, workdir: &str) -> Result, Error> { + let trace = Vec::::new(); + // TODO + Ok(trace) + } +} \ No newline at end of file diff --git a/libpresifuzz_feedbacks/src/differential_feedback.rs b/libpresifuzz_feedbacks/src/differential_feedback.rs new file mode 100644 index 0000000..28e8069 --- /dev/null +++ b/libpresifuzz_feedbacks/src/differential_feedback.rs @@ -0,0 +1,89 @@ +// SPDX-FileCopyrightText: 2022 Intel Corporation +// +// SPDX-License-Identifier: Apache-2.0 + +use std::str; +use core::{fmt::Debug}; +use serde::{Deserialize, Serialize}; +use libafl::{ + events::EventFirer, + executors::ExitKind, + inputs::{UsesInput}, + observers::{ObserversTuple}, + Error, + feedbacks::Feedback, + state::{State}, +}; + +use libafl_bolts::Named; + +use libpresifuzz_observers::trace_observer::{ExecTrace, ExecTraceParser}; + + +#[derive(Clone, Serialize, Deserialize, Debug)] +pub struct DifferentialFeedback +{ + ref_observer_name: String, + core_observer_name: String, + rf_ob: R, + co_ob: C, +} + +impl Feedback for DifferentialFeedback +where + S: UsesInput + State, + R: ExecTraceParser, + C: ExecTraceParser, +{ + + #[allow(clippy::wrong_self_convention)] + fn is_interesting( + &mut self, + _state: &mut S, + _manager: &mut EM, + _input: &S::Input, + observers: &OT, + _exit_kind: &ExitKind, + ) -> Result + where + EM: EventFirer, + OT: ObserversTuple + { + let ref_observer = observers.match_name::>(&self.ref_observer_name).unwrap(); + let core_observer = observers.match_name::>(&self.core_observer_name).unwrap(); + + if core_observer.cnt() == ref_observer.cnt() { + Ok(false); + } + Ok(true) + } +} + +impl Named for DifferentialFeedback +{ + #[inline] + fn name(&self) -> &str { + self.core_observer_name.as_str() + } +} + +impl DifferentialFeedback +where + R: ExecTraceParser, + C: ExecTraceParser, +{ + #[must_use] + pub fn new(ref_observer_name: &'static str, core_observer_name: &'static str) -> Self { + Self { + core_observer_name: core_observer_name.to_string(), + ref_observer_name: ref_observer_name.to_string(), + rf_ob: R::new(), + co_ob: C::new(), + } + } +} + + + + + diff --git a/libpresifuzz_feedbacks/src/lib.rs b/libpresifuzz_feedbacks/src/lib.rs index e20b33e..81d2aed 100644 --- a/libpresifuzz_feedbacks/src/lib.rs +++ b/libpresifuzz_feedbacks/src/lib.rs @@ -8,3 +8,4 @@ pub mod verdi_feedback; pub mod verdi_xml_feedback; pub mod transferred; pub mod cycle_feedback; +pub mod differential_feedback; diff --git a/libpresifuzz_observers/Cargo.toml b/libpresifuzz_observers/Cargo.toml index d68147d..0203429 100644 --- a/libpresifuzz_observers/Cargo.toml +++ b/libpresifuzz_observers/Cargo.toml @@ -47,3 +47,4 @@ rand = "0.8.5" tempfile = "3.9.0" flate2 = "1.0" quick-xml = "0.32.0" +regex = "1" \ No newline at end of file diff --git a/libpresifuzz_observers/spike.log b/libpresifuzz_observers/spike.log new file mode 100644 index 0000000..270c0ff --- /dev/null +++ b/libpresifuzz_observers/spike.log @@ -0,0 +1,313 @@ +core 0: 0x0000000000001000 (0x00000297) auipc t0, 0x0 +core 0: 3 0x0000000000001000 (0x00000297) x5 0x0000000000001000 +core 0: 0x0000000000001004 (0x02028593) addi a1, t0, 32 +core 0: 3 0x0000000000001004 (0x02028593) x11 0x0000000000001020 +core 0: 0x0000000000001008 (0xf1402573) csrr a0, mhartid +core 0: 3 0x0000000000001008 (0xf1402573) x10 0x0000000000000000 +core 0: 0x000000000000100c (0x0182b283) ld t0, 24(t0) +core 0: 3 0x000000000000100c (0x0182b283) x5 0x0000000080000000 mem 0x0000000000001018 +core 0: 0x0000000000001010 (0x00028067) jr t0 +core 0: 3 0x0000000000001010 (0x00028067) +core 0: >>>> _start +core 0: 0x0000000080000000 (0x00004081) c.li ra, 0 +core 0: 3 0x0000000080000000 (0x4081) x1 0x0000000000000000 +core 0: 0x0000000080000002 (0x00004101) c.li sp, 0 +core 0: 3 0x0000000080000002 (0x4101) x2 0x0000000000000000 +core 0: 0x0000000080000004 (0x00004181) c.li gp, 0 +core 0: 3 0x0000000080000004 (0x4181) x3 0x0000000000000000 +core 0: 0x0000000080000006 (0x00004201) c.li tp, 0 +core 0: 3 0x0000000080000006 (0x4201) x4 0x0000000000000000 +core 0: 0x0000000080000008 (0x00004281) c.li t0, 0 +core 0: 3 0x0000000080000008 (0x4281) x5 0x0000000000000000 +core 0: 0x000000008000000a (0x00004301) c.li t1, 0 +core 0: 3 0x000000008000000a (0x4301) x6 0x0000000000000000 +core 0: 0x000000008000000c (0x00004381) c.li t2, 0 +core 0: 3 0x000000008000000c (0x4381) x7 0x0000000000000000 +core 0: 0x000000008000000e (0x00004401) c.li s0, 0 +core 0: 3 0x000000008000000e (0x4401) x8 0x0000000000000000 +core 0: 0x0000000080000010 (0x00004481) c.li s1, 0 +core 0: 3 0x0000000080000010 (0x4481) x9 0x0000000000000000 +core 0: 0x0000000080000012 (0x00004501) c.li a0, 0 +core 0: 3 0x0000000080000012 (0x4501) x10 0x0000000000000000 +core 0: 0x0000000080000014 (0x00004581) c.li a1, 0 +core 0: 3 0x0000000080000014 (0x4581) x11 0x0000000000000000 +core 0: 0x0000000080000016 (0x00004601) c.li a2, 0 +core 0: 3 0x0000000080000016 (0x4601) x12 0x0000000000000000 +core 0: 0x0000000080000018 (0x00004681) c.li a3, 0 +core 0: 3 0x0000000080000018 (0x4681) x13 0x0000000000000000 +core 0: 0x000000008000001a (0x00004701) c.li a4, 0 +core 0: 3 0x000000008000001a (0x4701) x14 0x0000000000000000 +core 0: 0x000000008000001c (0x00004781) c.li a5, 0 +core 0: 3 0x000000008000001c (0x4781) x15 0x0000000000000000 +core 0: 0x000000008000001e (0x00004801) c.li a6, 0 +core 0: 3 0x000000008000001e (0x4801) x16 0x0000000000000000 +core 0: 0x0000000080000020 (0x00004881) c.li a7, 0 +core 0: 3 0x0000000080000020 (0x4881) x17 0x0000000000000000 +core 0: 0x0000000080000022 (0x00004901) c.li s2, 0 +core 0: 3 0x0000000080000022 (0x4901) x18 0x0000000000000000 +core 0: 0x0000000080000024 (0x00004981) c.li s3, 0 +core 0: 3 0x0000000080000024 (0x4981) x19 0x0000000000000000 +core 0: 0x0000000080000026 (0x00004a01) c.li s4, 0 +core 0: 3 0x0000000080000026 (0x4a01) x20 0x0000000000000000 +core 0: 0x0000000080000028 (0x00004a81) c.li s5, 0 +core 0: 3 0x0000000080000028 (0x4a81) x21 0x0000000000000000 +core 0: 0x000000008000002a (0x00004b01) c.li s6, 0 +core 0: 3 0x000000008000002a (0x4b01) x22 0x0000000000000000 +core 0: 0x000000008000002c (0x00004b81) c.li s7, 0 +core 0: 3 0x000000008000002c (0x4b81) x23 0x0000000000000000 +core 0: 0x000000008000002e (0x00004c01) c.li s8, 0 +core 0: 3 0x000000008000002e (0x4c01) x24 0x0000000000000000 +core 0: 0x0000000080000030 (0x00004c81) c.li s9, 0 +core 0: 3 0x0000000080000030 (0x4c81) x25 0x0000000000000000 +core 0: 0x0000000080000032 (0x00004d01) c.li s10, 0 +core 0: 3 0x0000000080000032 (0x4d01) x26 0x0000000000000000 +core 0: 0x0000000080000034 (0x00004d81) c.li s11, 0 +core 0: 3 0x0000000080000034 (0x4d81) x27 0x0000000000000000 +core 0: 0x0000000080000036 (0x00004e01) c.li t3, 0 +core 0: 3 0x0000000080000036 (0x4e01) x28 0x0000000000000000 +core 0: 0x0000000080000038 (0x00004e81) c.li t4, 0 +core 0: 3 0x0000000080000038 (0x4e81) x29 0x0000000000000000 +core 0: 0x000000008000003a (0x00004f01) c.li t5, 0 +core 0: 3 0x000000008000003a (0x4f01) x30 0x0000000000000000 +core 0: 0x000000008000003c (0x00004f81) c.li t6, 0 +core 0: 3 0x000000008000003c (0x4f81) x31 0x0000000000000000 +core 0: 0x000000008000003e (0x000062f9) c.lui t0, 0x1e +core 0: 3 0x000000008000003e (0x62f9) x5 0x000000000001e000 +core 0: 0x0000000080000040 (0x3002a073) csrs mstatus, t0 +core 0: 3 0x0000000080000040 (0x3002a073) c768_mstatus 0x8000000a00006000 +core 0: 0x0000000080000044 (0x00004285) c.li t0, 1 +core 0: 3 0x0000000080000044 (0x4285) x5 0x0000000000000001 +core 0: 0x0000000080000046 (0x000002fe) c.slli t0, 31 +core 0: 3 0x0000000080000046 (0x02fe) x5 0x0000000080000000 +core 0: 0x0000000080000048 (0x0002d863) bgez t0, pc + 16 +core 0: 3 0x0000000080000048 (0x0002d863) +core 0: 0x0000000080000058 (0x00000297) auipc t0, 0x0 +core 0: 3 0x0000000080000058 (0x00000297) x5 0x0000000080000058 +core 0: 0x000000008000005c (0x09028293) addi t0, t0, 144 +core 0: 3 0x000000008000005c (0x09028293) x5 0x00000000800000e8 +core 0: 0x0000000080000060 (0x30529073) csrw mtvec, t0 +core 0: 3 0x0000000080000060 (0x30529073) c773_mtvec 0x00000000800000e8 +core 0: 0x0000000080000064 (0x00301073) csrw fcsr, zero +core 0: 3 0x0000000080000064 (0x00301073) c1_fflags 0x0000000000000000 c2_frm 0x0000000000000000 +core 0: 0x0000000080000068 (0xf0000053) fmv.w.x ft0, zero +core 0: 3 0x0000000080000068 (0xf0000053) f0 0xffffffff00000000 +core 0: 0x000000008000006c (0xf00000d3) fmv.w.x ft1, zero +core 0: 3 0x000000008000006c (0xf00000d3) f1 0xffffffff00000000 +core 0: 0x0000000080000070 (0xf0000153) fmv.w.x ft2, zero +core 0: 3 0x0000000080000070 (0xf0000153) f2 0xffffffff00000000 +core 0: 0x0000000080000074 (0xf00001d3) fmv.w.x ft3, zero +core 0: 3 0x0000000080000074 (0xf00001d3) f3 0xffffffff00000000 +core 0: 0x0000000080000078 (0xf0000253) fmv.w.x ft4, zero +core 0: 3 0x0000000080000078 (0xf0000253) f4 0xffffffff00000000 +core 0: 0x000000008000007c (0xf00002d3) fmv.w.x ft5, zero +core 0: 3 0x000000008000007c (0xf00002d3) f5 0xffffffff00000000 +core 0: 0x0000000080000080 (0xf0000353) fmv.w.x ft6, zero +core 0: 3 0x0000000080000080 (0xf0000353) f6 0xffffffff00000000 +core 0: 0x0000000080000084 (0xf00003d3) fmv.w.x ft7, zero +core 0: 3 0x0000000080000084 (0xf00003d3) f7 0xffffffff00000000 +core 0: 0x0000000080000088 (0xf0000453) fmv.w.x fs0, zero +core 0: 3 0x0000000080000088 (0xf0000453) f8 0xffffffff00000000 +core 0: 0x000000008000008c (0xf00004d3) fmv.w.x fs1, zero +core 0: 3 0x000000008000008c (0xf00004d3) f9 0xffffffff00000000 +core 0: 0x0000000080000090 (0xf0000553) fmv.w.x fa0, zero +core 0: 3 0x0000000080000090 (0xf0000553) f10 0xffffffff00000000 +core 0: 0x0000000080000094 (0xf00005d3) fmv.w.x fa1, zero +core 0: 3 0x0000000080000094 (0xf00005d3) f11 0xffffffff00000000 +core 0: 0x0000000080000098 (0xf0000653) fmv.w.x fa2, zero +core 0: 3 0x0000000080000098 (0xf0000653) f12 0xffffffff00000000 +core 0: 0x000000008000009c (0xf00006d3) fmv.w.x fa3, zero +core 0: 3 0x000000008000009c (0xf00006d3) f13 0xffffffff00000000 +core 0: 0x00000000800000a0 (0xf0000753) fmv.w.x fa4, zero +core 0: 3 0x00000000800000a0 (0xf0000753) f14 0xffffffff00000000 +core 0: 0x00000000800000a4 (0xf00007d3) fmv.w.x fa5, zero +core 0: 3 0x00000000800000a4 (0xf00007d3) f15 0xffffffff00000000 +core 0: 0x00000000800000a8 (0xf0000853) fmv.w.x fa6, zero +core 0: 3 0x00000000800000a8 (0xf0000853) f16 0xffffffff00000000 +core 0: 0x00000000800000ac (0xf00008d3) fmv.w.x fa7, zero +core 0: 3 0x00000000800000ac (0xf00008d3) f17 0xffffffff00000000 +core 0: 0x00000000800000b0 (0xf0000953) fmv.w.x fs2, zero +core 0: 3 0x00000000800000b0 (0xf0000953) f18 0xffffffff00000000 +core 0: 0x00000000800000b4 (0xf00009d3) fmv.w.x fs3, zero +core 0: 3 0x00000000800000b4 (0xf00009d3) f19 0xffffffff00000000 +core 0: 0x00000000800000b8 (0xf0000a53) fmv.w.x fs4, zero +core 0: 3 0x00000000800000b8 (0xf0000a53) f20 0xffffffff00000000 +core 0: 0x00000000800000bc (0xf0000ad3) fmv.w.x fs5, zero +core 0: 3 0x00000000800000bc (0xf0000ad3) f21 0xffffffff00000000 +core 0: 0x00000000800000c0 (0xf0000b53) fmv.w.x fs6, zero +core 0: 3 0x00000000800000c0 (0xf0000b53) f22 0xffffffff00000000 +core 0: 0x00000000800000c4 (0xf0000bd3) fmv.w.x fs7, zero +core 0: 3 0x00000000800000c4 (0xf0000bd3) f23 0xffffffff00000000 +core 0: 0x00000000800000c8 (0xf0000c53) fmv.w.x fs8, zero +core 0: 3 0x00000000800000c8 (0xf0000c53) f24 0xffffffff00000000 +core 0: 0x00000000800000cc (0xf0000cd3) fmv.w.x fs9, zero +core 0: 3 0x00000000800000cc (0xf0000cd3) f25 0xffffffff00000000 +core 0: 0x00000000800000d0 (0xf0000d53) fmv.w.x fs10, zero +core 0: 3 0x00000000800000d0 (0xf0000d53) f26 0xffffffff00000000 +core 0: 0x00000000800000d4 (0xf0000dd3) fmv.w.x fs11, zero +core 0: 3 0x00000000800000d4 (0xf0000dd3) f27 0xffffffff00000000 +core 0: 0x00000000800000d8 (0xf0000e53) fmv.w.x ft8, zero +core 0: 3 0x00000000800000d8 (0xf0000e53) f28 0xffffffff00000000 +core 0: 0x00000000800000dc (0xf0000ed3) fmv.w.x ft9, zero +core 0: 3 0x00000000800000dc (0xf0000ed3) f29 0xffffffff00000000 +core 0: 0x00000000800000e0 (0xf0000f53) fmv.w.x ft10, zero +core 0: 3 0x00000000800000e0 (0xf0000f53) f30 0xffffffff00000000 +core 0: 0x00000000800000e4 (0xf0000fd3) fmv.w.x ft11, zero +core 0: 3 0x00000000800000e4 (0xf0000fd3) f31 0xffffffff00000000 +core 0: 0x00000000800000e8 (0x00000297) auipc t0, 0x0 +core 0: 3 0x00000000800000e8 (0x00000297) x5 0x00000000800000e8 +core 0: 0x00000000800000ec (0x03c28293) addi t0, t0, 60 +core 0: 3 0x00000000800000ec (0x03c28293) x5 0x0000000080000124 +core 0: 0x00000000800000f0 (0x30529073) csrw mtvec, t0 +core 0: 3 0x00000000800000f0 (0x30529073) c773_mtvec 0x0000000080000124 +core 0: 0x00000000800000f4 (0x00003197) auipc gp, 0x3 +core 0: 3 0x00000000800000f4 (0x00003197) x3 0x00000000800030f4 +core 0: 0x00000000800000f8 (0x79218193) addi gp, gp, 1938 +core 0: 3 0x00000000800000f8 (0x79218193) x3 0x0000000080003886 +core 0: 0x00000000800000fc (0x00003217) auipc tp, 0x3 +core 0: 3 0x00000000800000fc (0x00003217) x4 0x00000000800030fc +core 0: 0x0000000080000100 (0xfc920213) addi tp, tp, -55 +core 0: 3 0x0000000080000100 (0xfc920213) x4 0x00000000800030c5 +core 0: 0x0000000080000104 (0xfc027213) andi tp, tp, -64 +core 0: 3 0x0000000080000104 (0xfc027213) x4 0x00000000800030c0 +core 0: 0x0000000080000108 (0xf1402573) csrr a0, mhartid +core 0: 3 0x0000000080000108 (0xf1402573) x10 0x0000000000000000 +core 0: 0x000000008000010c (0x00004585) c.li a1, 1 +core 0: 3 0x000000008000010c (0x4585) x11 0x0000000000000001 +core 0: 0x000000008000010e (0x00b57063) bgeu a0, a1, pc + 0 +core 0: 3 0x000000008000010e (0x00b57063) +core 0: 0x0000000080000112 (0x00150113) addi sp, a0, 1 +core 0: 3 0x0000000080000112 (0x00150113) x2 0x0000000000000001 +core 0: 0x0000000080000116 (0x00000146) c.slli sp, 17 +core 0: 3 0x0000000080000116 (0x0146) x2 0x0000000000020000 +core 0: 0x0000000080000118 (0x00009112) c.add sp, tp +core 0: 3 0x0000000080000118 (0x9112) x2 0x00000000800230c0 +core 0: 0x000000008000011a (0x01151613) slli a2, a0, 17 +core 0: 3 0x000000008000011a (0x01151613) x12 0x0000000000000000 +core 0: 0x000000008000011e (0x00009232) c.add tp, a2 +core 0: 3 0x000000008000011e (0x9232) x4 0x00000000800030c0 +core 0: 0x0000000080000120 (0x0a80006f) j pc + 0xa8 +core 0: 3 0x0000000080000120 (0x0a80006f) +core 0: >>>> _init +core 0: 0x00000000800001c8 (0x63d010ef) jal pc + 0x1e3c +core 0: 3 0x00000000800001c8 (0x63d010ef) x1 0x00000000800001cc +core 0: >>>> main +core 0: 0x0000000080002004 (0x00000297) auipc t0, 0x0 +core 0: 3 0x0000000080002004 (0x00000297) x5 0x0000000080002004 +core 0: 0x0000000080002008 (0x01c28293) addi t0, t0, 28 +core 0: 3 0x0000000080002008 (0x01c28293) x5 0x0000000080002020 +core 0: 0x000000008000200c (0x30529073) csrw mtvec, t0 +core 0: 3 0x000000008000200c (0x30529073) c773_mtvec 0x0000000080002020 +core 0: 0x0000000080002010 (0x00000e97) auipc t4, 0x0 +core 0: 3 0x0000000080002010 (0x00000e97) x29 0x0000000080002010 +core 0: 0x0000000080002014 (0xff0e8e93) addi t4, t4, -16 +core 0: 3 0x0000000080002014 (0xff0e8e93) x29 0x0000000080002000 +core 0: 0x0000000080002018 (0x000ea023) sw zero, 0(t4) +core 0: 3 0x0000000080002018 (0x000ea023) mem 0x0000000080002000 0x00000000 +core 0: 0x000000008000201c (0x0640006f) j pc + 0x64 +core 0: 3 0x000000008000201c (0x0640006f) +core 0: >>>> $d +core 0: 0x0000000080002080 (0xdeadbeef) jal t4, pc - 0x24a16 +core 0: 3 0x0000000080002080 (0xdeadbeef) x29 0x0000000080002084 +core 0: exception trap_instruction_access_fault, epc 0x000000007ffdd66a +core 0: tval 0x000000007ffdd66a +core 0: >>>> exception_entry +core 0: 0x0000000080002020 (0x341022f3) csrr t0, mepc +core 0: 3 0x0000000080002020 (0x341022f3) x5 0x000000007ffdd66a +core 0: 0x0000000080002024 (0x00028303) lb t1, 0(t0) +core 0: exception trap_load_access_fault, epc 0x0000000080002024 +core 0: tval 0x000000007ffdd66a +core 0: >>>> exception_entry +core 0: 0x0000000080002020 (0x341022f3) csrr t0, mepc +core 0: 3 0x0000000080002020 (0x341022f3) x5 0x0000000080002024 +core 0: 0x0000000080002024 (0x00028303) lb t1, 0(t0) +core 0: 3 0x0000000080002024 (0x00028303) x6 0x0000000000000003 mem 0x0000000080002024 +core 0: 0x0000000080002028 (0x0000450d) c.li a0, 3 +core 0: 3 0x0000000080002028 (0x450d) x10 0x0000000000000003 +core 0: 0x000000008000202a (0x00a37333) and t1, t1, a0 +core 0: 3 0x000000008000202a (0x00a37333) x6 0x0000000000000003 +core 0: 0x000000008000202e (0x00000e97) auipc t4, 0x0 +core 0: 3 0x000000008000202e (0x00000e97) x29 0x000000008000202e +core 0: 0x0000000080002032 (0xfd2e8e93) addi t4, t4, -46 +core 0: 3 0x0000000080002032 (0xfd2e8e93) x29 0x0000000080002000 +core 0: 0x0000000080002036 (0x000eaf03) lw t5, 0(t4) +core 0: 3 0x0000000080002036 (0x000eaf03) x30 0x0000000000000000 mem 0x0000000080002000 +core 0: 0x000000008000203a (0x00000f05) c.addi t5, 1 +core 0: 3 0x000000008000203a (0x0f05) x30 0x0000000000000001 +core 0: 0x000000008000203c (0x00004fa9) c.li t6, 10 +core 0: 3 0x000000008000203c (0x4fa9) x31 0x000000000000000a +core 0: 0x000000008000203e (0x03ff0163) beq t5, t6, pc + 34 +core 0: 3 0x000000008000203e (0x03ff0163) +core 0: 0x0000000080002042 (0x01eea023) sw t5, 0(t4) +core 0: 3 0x0000000080002042 (0x01eea023) mem 0x0000000080002000 0x00000001 +core 0: 0x0000000080002046 (0x00a31363) bne t1, a0, pc + 6 +core 0: 3 0x0000000080002046 (0x00a31363) +core 0: 0x000000008000204a (0x00000289) c.addi t0, 2 +core 0: 3 0x000000008000204a (0x0289) x5 0x0000000080002026 +core 0: >>>> end_handler_incr_mepc2 +core 0: 0x000000008000204c (0x00000289) c.addi t0, 2 +core 0: 3 0x000000008000204c (0x0289) x5 0x0000000080002028 +core 0: 0x000000008000204e (0x34129073) csrw mepc, t0 +core 0: 3 0x000000008000204e (0x34129073) c833_mepc 0x0000000080002028 +core 0: >>>> end_handler_ret +core 0: 0x0000000080002052 (0x30200073) mret +core 0: 3 0x0000000080002052 (0x30200073) c1957_tcontrol 0x0000000000000000 c768_mstatus 0x8000000a00006080 +core 0: 0x0000000080002028 (0x0000450d) c.li a0, 3 +core 0: 3 0x0000000080002028 (0x450d) x10 0x0000000000000003 +core 0: 0x000000008000202a (0x00a37333) and t1, t1, a0 +core 0: 3 0x000000008000202a (0x00a37333) x6 0x0000000000000003 +core 0: 0x000000008000202e (0x00000e97) auipc t4, 0x0 +core 0: 3 0x000000008000202e (0x00000e97) x29 0x000000008000202e +core 0: 0x0000000080002032 (0xfd2e8e93) addi t4, t4, -46 +core 0: 3 0x0000000080002032 (0xfd2e8e93) x29 0x0000000080002000 +core 0: 0x0000000080002036 (0x000eaf03) lw t5, 0(t4) +core 0: 3 0x0000000080002036 (0x000eaf03) x30 0x0000000000000001 mem 0x0000000080002000 +core 0: 0x000000008000203a (0x00000f05) c.addi t5, 1 +core 0: 3 0x000000008000203a (0x0f05) x30 0x0000000000000002 +core 0: 0x000000008000203c (0x00004fa9) c.li t6, 10 +core 0: 3 0x000000008000203c (0x4fa9) x31 0x000000000000000a +core 0: 0x000000008000203e (0x03ff0163) beq t5, t6, pc + 34 +core 0: 3 0x000000008000203e (0x03ff0163) +core 0: 0x0000000080002042 (0x01eea023) sw t5, 0(t4) +core 0: 3 0x0000000080002042 (0x01eea023) mem 0x0000000080002000 0x00000002 +core 0: 0x0000000080002046 (0x00a31363) bne t1, a0, pc + 6 +core 0: 3 0x0000000080002046 (0x00a31363) +core 0: 0x000000008000204a (0x00000289) c.addi t0, 2 +core 0: 3 0x000000008000204a (0x0289) x5 0x000000008000202a +core 0: >>>> end_handler_incr_mepc2 +core 0: 0x000000008000204c (0x00000289) c.addi t0, 2 +core 0: 3 0x000000008000204c (0x0289) x5 0x000000008000202c +core 0: 0x000000008000204e (0x34129073) csrw mepc, t0 +core 0: 3 0x000000008000204e (0x34129073) c833_mepc 0x000000008000202c +core 0: >>>> end_handler_ret +core 0: 0x0000000080002052 (0x30200073) mret +core 0: 3 0x0000000080002052 (0x30200073) c1957_tcontrol 0x0000000000000000 c768_mstatus 0x8000000a00006088 +core 0: 0x000000008000202c (0x0e9700a3) sb s1, 225(a4) +core 0: exception trap_store_access_fault, epc 0x000000008000202c +core 0: tval 0x00000000000000e1 +core 0: >>>> exception_entry +core 0: 0x0000000080002020 (0x341022f3) csrr t0, mepc +core 0: 3 0x0000000080002020 (0x341022f3) x5 0x000000008000202c +core 0: 0x0000000080002024 (0x00028303) lb t1, 0(t0) +core 0: 3 0x0000000080002024 (0x00028303) x6 0xffffffffffffffa3 mem 0x000000008000202c +core 0: 0x0000000080002028 (0x0000450d) c.li a0, 3 +core 0: 3 0x0000000080002028 (0x450d) x10 0x0000000000000003 +core 0: 0x000000008000202a (0x00a37333) and t1, t1, a0 +core 0: 3 0x000000008000202a (0x00a37333) x6 0x0000000000000003 +core 0: 0x000000008000202e (0x00000e97) auipc t4, 0x0 +core 0: 3 0x000000008000202e (0x00000e97) x29 0x000000008000202e +core 0: 0x0000000080002032 (0xfd2e8e93) addi t4, t4, -46 +core 0: 3 0x0000000080002032 (0xfd2e8e93) x29 0x0000000080002000 +core 0: 0x0000000080002036 (0x000eaf03) lw t5, 0(t4) +core 0: 3 0x0000000080002036 (0x000eaf03) x30 0x0000000000000002 mem 0x0000000080002000 +core 0: 0x000000008000203a (0x00000f05) c.addi t5, 1 +core 0: 3 0x000000008000203a (0x0f05) x30 0x0000000000000003 +core 0: 0x000000008000203c (0x00004fa9) c.li t6, 10 +core 0: 3 0x000000008000203c (0x4fa9) x31 0x000000000000000a +core 0: 0x000000008000203e (0x03ff0163) beq t5, t6, pc + 34 +core 0: 3 0x000000008000203e (0x03ff0163) +core 0: 0x0000000080002042 (0x01eea023) sw t5, 0(t4) +core 0: 3 0x0000000080002042 (0x01eea023) mem 0x0000000080002000 0x00000003 +core 0: 0x0000000080002046 (0x00a31363) bne t1, a0, pc + 6 +core 0: 3 0x0000000080002046 (0x00a31363) +core 0: 0x000000008000204a (0x00000289) c.addi t0, 2 +core 0: 3 0x000000008000204a (0x0289) x5 0x000000008000202e \ No newline at end of file diff --git a/libpresifuzz_observers/src/lib.rs b/libpresifuzz_observers/src/lib.rs index 65da3ac..576935a 100644 --- a/libpresifuzz_observers/src/lib.rs +++ b/libpresifuzz_observers/src/lib.rs @@ -4,4 +4,4 @@ pub mod verdi_observer; pub mod verdi_xml_observer; - +pub mod trace_observer; diff --git a/libpresifuzz_observers/src/trace_observer.rs b/libpresifuzz_observers/src/trace_observer.rs new file mode 100644 index 0000000..80abb54 --- /dev/null +++ b/libpresifuzz_observers/src/trace_observer.rs @@ -0,0 +1,235 @@ +// SPDX-FileCopyrightText: 2022 Intel Corporation +// +// SPDX-License-Identifier: Apache-2.0 + +use libafl::{ + executors::{ExitKind}, + observers::{Observer}, + Error, + inputs::{UsesInput}, +}; + +use core::{fmt::Debug}; +use serde::{Deserialize, Serialize}; +use libafl_bolts::{HasLen, Named}; + +use std::fs::File; + +extern crate fs_extra; +use std::{str}; +use regex::Regex; +use std::io::{self, BufRead}; + + + + +#[derive(Copy, Clone, Serialize, Deserialize, Debug)] +pub enum OpType { + Read, + Write, +} + +#[derive(Copy, Clone, Serialize, Deserialize, Debug)] +pub struct MemOp { + pub op_type: OpType, + pub address: u64, + pub value: u64, + +} + +#[derive(Clone, Serialize, Deserialize, Debug)] +pub struct RegOp { + pub op_type: OpType, + pub name: String, + pub value: u64, + +} + +#[derive(Clone, Serialize, Deserialize, Debug)] +pub enum OpLog { + RegOp(RegOp), + MemOp(MemOp), +} + +#[derive(Clone, Serialize, Deserialize, Debug)] +pub struct TraceLog { + pub pc: u64, + pub inst: u64, + pub ops: Vec, +} + +pub trait ExecTraceParser { + fn new() -> Self; + fn parse(&self, workdir: &str) -> Result, Error> ; +} + +#[derive(Clone, Serialize, Deserialize, Debug)] +#[allow(clippy::unsafe_derive_deserialize)] +pub struct ExecTrace +{ + name: String, + workdir: String, + trace: Vec, + trace_parser: T, +} + +impl ExecTrace +where + T: ExecTraceParser, +{ + pub fn new(name: &str, workdir: &str) -> Self { + Self { + name: name.to_string(), + trace: Vec::::new(), + workdir: workdir.to_string(), + trace_parser: T::new(), + } + } + + pub fn cnt(&self) -> usize { + self.trace.len() + } +} + + +impl Named for ExecTrace +where + T: ExecTraceParser, +{ + fn name(&self) -> &str { + &self.name + } +} + +impl HasLen for ExecTrace +where + T: ExecTraceParser, +{ + fn len(&self) -> usize { + self.trace.len() + } +} + +impl Observer for ExecTrace +where + S: UsesInput, + T: ExecTraceParser, +{ + fn pre_exec(&mut self, _state: &mut S, _input: &S::Input) -> Result<(), Error> { + Ok(()) + } + + #[inline] + fn post_exec( + &mut self, + _state: &mut S, + _input: &S::Input, + _exit_kind: &ExitKind, + ) -> Result<(), Error> { + + self.trace = self.trace_parser.parse(&self.workdir).unwrap(); + + Ok(()) + } +} + +#[derive(Copy, Clone, Serialize, Deserialize, Debug)] +pub struct SpikeExecTrace; + +impl ExecTraceParser for SpikeExecTrace +{ + fn new() -> Self { + SpikeExecTrace {} + } + fn parse(&self, workdir: &str) -> Result, Error> { + let mut trace = Vec::::new(); + + let spike_file = format!("{}/spike.err", workdir); + + let file = File::open(spike_file).expect("Unable to open spike trace file"); + let reader = io::BufReader::new(file); + + let spike_store_commit_re = Regex::new(r"core\s+\d+: \d+ 0x(\w+) \(0x(\w+)\)\s+mem\s+0x(\w+)\s+0x(\w+)").unwrap(); + let spike_rest_commit_re = Regex::new(r"core\s+\d+: \d+ 0x(\w+) \(0x(\w+)\)\s+(\w+)\s+0x(\w+)(\s+(\w+)\s+0x(\w+))?").unwrap(); + for line in reader.lines() { + if let Ok(log_line) = &line { + if let Some(caps) = spike_store_commit_re.captures(log_line) { + let ops = vec![ + OpLog::MemOp(MemOp{op_type: OpType::Write, address: u64::from_str_radix(&caps[3], 16).unwrap(), value: u64::from_str_radix(&caps[4], 16).unwrap()}) + ]; + trace.push(TraceLog { + pc: u64::from_str_radix(&caps[1], 16).unwrap(), + inst: u64::from_str_radix(&caps[2], 16).unwrap(), + ops, + }); + } + else if let Some(caps) = spike_rest_commit_re.captures(log_line) { + let mut ops = vec![ + OpLog::RegOp(RegOp{op_type: OpType::Read, name: caps[3].to_string(), value: u64::from_str_radix(&caps[4], 16).unwrap()}) + ]; + + if caps.get(5) != None && &caps[6] == "mem" { + ops.push(OpLog::MemOp(MemOp{op_type: OpType::Read, address: u64::from_str_radix(&caps[7], 16).unwrap(), value: u64::from_str_radix(&caps[4], 16).unwrap()})); + } else if caps.get(5) != None { + ops.push(OpLog::RegOp(RegOp{op_type: OpType::Read, name: caps[6].to_string(), value: u64::from_str_radix(&caps[7], 16).unwrap()})); + } + + trace.push(TraceLog { + pc: u64::from_str_radix(&caps[1], 16).unwrap(), + inst: u64::from_str_radix(&caps[2], 16).unwrap(), + ops, + }); + } + } + } + Ok(trace) + } +} + + + +// TODO: Re-enable this test using vdb from open source design +#[cfg(feature = "std")] +#[cfg(test)] +mod tests { + + extern crate fs_extra; + use libafl_bolts::prelude::StdRand; + use libafl::prelude::BytesInput; + use libafl::executors::{ExitKind}; + use libafl_bolts::current_time; + use libafl::prelude::InMemoryCorpus; + use libafl::prelude::ConstFeedback; + use crate::trace_observer::{ExecTrace, SpikeExecTrace}; + use libafl::prelude::StdState; + use libafl::state::HasMaxSize; + use libafl::observers::Observer; + + #[test] + fn test_spike_trace_observer() { + + let input = BytesInput::new(vec![1, 2, 3, 4]); + + let rand = StdRand::with_seed(current_time().as_nanos() as u64); + let corpus = InMemoryCorpus::::new(); + + let mut feedback = ConstFeedback::new(true); + let mut objective = ConstFeedback::new(false); + + let mut spike_trace_observer = ExecTrace::::new("spike_trace", "./"); + + let mut state = StdState::new( + rand, + corpus, + InMemoryCorpus::::new(), + &mut feedback, + &mut objective, + ) + .unwrap(); + state.set_max_size(1024); + + let _ = spike_trace_observer.post_exec(&mut state, &input, &ExitKind::Ok); + println!("{:?}", spike_trace_observer.trace.len()) + } +} + diff --git a/libpresifuzz_observers/src/verdi_observer.rs b/libpresifuzz_observers/src/verdi_observer.rs index 4b68e69..ae9bc79 100644 --- a/libpresifuzz_observers/src/verdi_observer.rs +++ b/libpresifuzz_observers/src/verdi_observer.rs @@ -18,7 +18,7 @@ use core::{ }; use serde::{Deserialize, Serialize}; use libc::{c_uint, c_char, c_void}; -use nix::{sys::wait::waitpid,unistd::{fork, ForkResult, dup2, close}}; +use nix::{unistd::{fork, ForkResult, dup2, close}}; use libafl_bolts::{ ownedref::OwnedMutSlice, AsIter, AsIterMut, AsMutSlice, AsSlice, HasLen, Named, }; diff --git a/libpresifuzz_observers/src/verdi_xml_observer.rs b/libpresifuzz_observers/src/verdi_xml_observer.rs index dc5f514..068d8f1 100644 --- a/libpresifuzz_observers/src/verdi_xml_observer.rs +++ b/libpresifuzz_observers/src/verdi_xml_observer.rs @@ -219,7 +219,6 @@ where }; let xml_file = format!("{}/{}/snps/coverage/db/testdata/test/{}", self.workdir, self.vdb, xml_file); - let xml_file_ = xml_file.clone(); // Open the gzip-compressed file let mut coverage_file = File::open(xml_file).expect("Unable to open file xml coverage file"); @@ -244,9 +243,7 @@ where // Find the start and end of the name attribute if let Some(name_start) = line.find(r#"name=""#) { let name_start = name_start + r#"name=""#.len(); - if let Some(name_end) = line[name_start..].find('"') { - let name = &line[name_start..name_start + name_end]; - + if line[name_start..].find('"').is_some() { // Find the start and end of the value attribute if let Some(value_start) = line.find(r#"value=""#) { let value_start = value_start + r#"value=""#.len(); @@ -352,7 +349,6 @@ mod tests { extern crate fs_extra; use libc::{c_uint, c_char, c_void}; - use nix::{sys::wait::waitpid,unistd::{fork, ForkResult}}; use std::process; use libafl_bolts::prelude::StdRand; use libafl::prelude::BytesInput;