Various improvements
Replace TimeObserver with ClockObserver Add a Maximization Scheduler for Clocks Factor out icount Metadata from Feedback Allow Breakpoint removal in systemmode
This commit is contained in:
parent
2ead941419
commit
06d382bff8
@ -1,6 +1,9 @@
|
|||||||
//! A singlethreaded QEMU fuzzer that can auto-restart.
|
//! A singlethreaded QEMU fuzzer that can auto-restart.
|
||||||
|
|
||||||
use libafl_qemu::QemuClockObserver;
|
use libafl::mutators::ByteFlipMutator;
|
||||||
|
use libafl::mutators::BitFlipMutator;
|
||||||
|
use crate::worst::LenTimeMaximizerCorpusScheduler;
|
||||||
|
use libafl::corpus::MinimizerCorpusScheduler;
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use libafl::events::SimpleEventManager;
|
use libafl::events::SimpleEventManager;
|
||||||
use clap::{App, Arg};
|
use clap::{App, Arg};
|
||||||
@ -57,6 +60,10 @@ use libafl_qemu::{
|
|||||||
filter_qemu_args,
|
filter_qemu_args,
|
||||||
snapshot_sys::QemuSysSnapshotHelper,
|
snapshot_sys::QemuSysSnapshotHelper,
|
||||||
QemuExecutor,
|
QemuExecutor,
|
||||||
|
clock,
|
||||||
|
QemuClockObserver,
|
||||||
|
clock::ClockFeedback,
|
||||||
|
clock::QemuClockIncreaseFeedback
|
||||||
};
|
};
|
||||||
use crate::worst::{HitFeedback,HitcountsMapObserver,HitImprovingFeedback};
|
use crate::worst::{HitFeedback,HitcountsMapObserver,HitImprovingFeedback};
|
||||||
|
|
||||||
@ -283,7 +290,7 @@ fn fuzz(
|
|||||||
HitcountsMapObserver::new(VariableMapObserver::new("edges", edges, edges_counter));
|
HitcountsMapObserver::new(VariableMapObserver::new("edges", edges, edges_counter));
|
||||||
|
|
||||||
// Create an observation channel to keep track of the execution time
|
// Create an observation channel to keep track of the execution time
|
||||||
let time_observer = TimeObserver::new("time");
|
// let time_observer = TimeObserver::new("time");
|
||||||
let clock_observer = QemuClockObserver::default();
|
let clock_observer = QemuClockObserver::default();
|
||||||
|
|
||||||
// Create an observation channel using cmplog map
|
// Create an observation channel using cmplog map
|
||||||
@ -304,7 +311,9 @@ fn fuzz(
|
|||||||
};
|
};
|
||||||
let feedback = feedback_or!(
|
let feedback = feedback_or!(
|
||||||
MaxMapFeedback::new_tracking(&feedback_state, &edges_observer, true, false),
|
MaxMapFeedback::new_tracking(&feedback_state, &edges_observer, true, false),
|
||||||
HitImprovingFeedback::new(target_map.clone())
|
HitImprovingFeedback::new(target_map.clone()),
|
||||||
|
QemuClockIncreaseFeedback::default(),
|
||||||
|
ClockFeedback::new_with_observer(&clock_observer)
|
||||||
);
|
);
|
||||||
// let feedback = feedback_or!(
|
// let feedback = feedback_or!(
|
||||||
// // New maximization map feedback linked to the edges observer and the feedback state
|
// // New maximization map feedback linked to the edges observer and the feedback state
|
||||||
@ -329,7 +338,7 @@ fn fuzz(
|
|||||||
OnDiskCorpus::new(objective_dir).unwrap(),
|
OnDiskCorpus::new(objective_dir).unwrap(),
|
||||||
// States of the feedbacks.
|
// States of the feedbacks.
|
||||||
// They are the data related to the feedbacks that you want to persist in the State.
|
// They are the data related to the feedbacks that you want to persist in the State.
|
||||||
tuple_list!(feedback_state),
|
tuple_list!(feedback_state,clock::MaxIcountMetadata::default()),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -380,7 +389,7 @@ fn fuzz(
|
|||||||
//QemuAsanHelper::new(),
|
//QemuAsanHelper::new(),
|
||||||
QemuSysSnapshotHelper::new()
|
QemuSysSnapshotHelper::new()
|
||||||
),
|
),
|
||||||
tuple_list!(edges_observer, time_observer, clock_observer),
|
tuple_list!(edges_observer, clock_observer),
|
||||||
&mut fuzzer,
|
&mut fuzzer,
|
||||||
&mut state,
|
&mut state,
|
||||||
&mut mgr,
|
&mut mgr,
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
use libafl::feedbacks::MapIndexesMetadata;
|
||||||
|
use libafl::corpus::Testcase;
|
||||||
|
use libafl::corpus::FavFactor;
|
||||||
|
use core::marker::PhantomData;
|
||||||
|
use libafl::corpus::MinimizerCorpusScheduler;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use libafl::observers::VariableMapObserver;
|
use libafl::observers::VariableMapObserver;
|
||||||
@ -185,7 +190,7 @@ where
|
|||||||
}
|
}
|
||||||
let mean_sum_of_squares = (sum_of_square_difference as f64) / (self.target_map.len() as f64);
|
let mean_sum_of_squares = (sum_of_square_difference as f64) / (self.target_map.len() as f64);
|
||||||
let hit_target = mean_sum_of_squares <= self.target_msd;
|
let hit_target = mean_sum_of_squares <= self.target_msd;
|
||||||
eprintln!("hit target: {} {} {:?}",hit_target,mean_sum_of_squares, _input);
|
// eprintln!("hit target: {} {} {:?}",hit_target,mean_sum_of_squares, _input);
|
||||||
if hit_target {
|
if hit_target {
|
||||||
Ok(true)
|
Ok(true)
|
||||||
} else {
|
} else {
|
||||||
@ -314,9 +319,10 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
let mean_sum_of_squares = (sum_of_square_difference as f64) / (self.target_map.len() as f64);
|
let mean_sum_of_squares = (sum_of_square_difference as f64) / (self.target_map.len() as f64);
|
||||||
let hit_target = mean_sum_of_squares <= self.best_msd;
|
let hit_target = mean_sum_of_squares < self.best_msd;
|
||||||
eprintln!("improving: {}",hit_target);
|
// eprintln!("improving: {}",hit_target);
|
||||||
if hit_target {
|
if hit_target {
|
||||||
|
// println!("Hit Improving: {}",mean_sum_of_squares);
|
||||||
self.best_msd = mean_sum_of_squares;
|
self.best_msd = mean_sum_of_squares;
|
||||||
Ok(true)
|
Ok(true)
|
||||||
} else {
|
} else {
|
||||||
@ -408,7 +414,7 @@ impl Default for DumpMapFeedback {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//=========================== Debugging Feedback
|
//=========================== Debugging Feedback
|
||||||
/// A [`Feedback`] meant to dump the edgemap for debugging.
|
/// A NoOp [`Feedback`] with fixed response.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct DummyFeedback {
|
pub struct DummyFeedback {
|
||||||
response: bool
|
response: bool
|
||||||
@ -456,3 +462,27 @@ impl Default for DummyFeedback {
|
|||||||
Self::new(true)
|
Self::new(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub type LenTimeMaximizerCorpusScheduler<CS, I, S> =
|
||||||
|
MinimizerCorpusScheduler<CS, MaxLenTimeFavFactor<I>, I, MapIndexesMetadata, S>;
|
||||||
|
|
||||||
|
/// Multiply the testcase size with the execution time.
|
||||||
|
/// This favors small and quick testcases.
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct MaxLenTimeFavFactor<I>
|
||||||
|
where
|
||||||
|
I: Input + HasLen,
|
||||||
|
{
|
||||||
|
phantom: PhantomData<I>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I> FavFactor<I> for MaxLenTimeFavFactor<I>
|
||||||
|
where
|
||||||
|
I: Input + HasLen,
|
||||||
|
{
|
||||||
|
fn compute(entry: &mut Testcase<I>) -> Result<u64, Error> {
|
||||||
|
// TODO maybe enforce entry.exec_time().is_some()
|
||||||
|
let execs_per_hour = (3600.0/entry.exec_time().expect("testcase.exec_time is needed for scheduler").as_secs_f64()) as u64;
|
||||||
|
Ok(execs_per_hour)
|
||||||
|
}
|
||||||
|
}
|
@ -31,21 +31,66 @@ use libafl::feedbacks::Feedback;
|
|||||||
use libafl::SerdeAny;
|
use libafl::SerdeAny;
|
||||||
use libafl::state::HasMetadata;
|
use libafl::state::HasMetadata;
|
||||||
use libafl::corpus::testcase::Testcase;
|
use libafl::corpus::testcase::Testcase;
|
||||||
|
use core::{fmt::Debug, time::Duration};
|
||||||
|
use libafl::feedbacks::FeedbackState;
|
||||||
|
use libafl::state::HasFeedbackStates;
|
||||||
|
use libafl::bolts::tuples::MatchName;
|
||||||
|
|
||||||
//========== Metadata
|
//========== Metadata
|
||||||
#[derive(Debug, Serialize, Deserialize, SerdeAny)]
|
#[derive(Debug, Serialize, Deserialize, SerdeAny)]
|
||||||
pub struct QemuIcountMetadata {
|
pub struct QemuIcountMetadata {
|
||||||
runtime: i64,
|
runtime: u64,
|
||||||
}
|
}
|
||||||
// libafl::impl_serdeany!(QemuIcountMetadata);
|
// libafl::impl_serdeany!(QemuIcountMetadata);
|
||||||
|
|
||||||
|
/// Metadata for [`QemuClockIncreaseFeedback`]
|
||||||
|
#[derive(Debug, Serialize, Deserialize, SerdeAny)]
|
||||||
|
pub struct MaxIcountMetadata {
|
||||||
|
pub max_icount_seen: u64,
|
||||||
|
pub name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FeedbackState for MaxIcountMetadata
|
||||||
|
{
|
||||||
|
fn reset(&mut self) -> Result<(), Error> {
|
||||||
|
self.max_icount_seen = 0;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Named for MaxIcountMetadata
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn name(&self) -> &str {
|
||||||
|
self.name.as_str()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MaxIcountMetadata
|
||||||
|
{
|
||||||
|
/// Create new `MaxIcountMetadata`
|
||||||
|
#[must_use]
|
||||||
|
pub fn new(name: &'static str) -> Self {
|
||||||
|
Self {
|
||||||
|
max_icount_seen: 0,
|
||||||
|
name: name.to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for MaxIcountMetadata {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new("MaxClock")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//========== Observer
|
//========== Observer
|
||||||
|
|
||||||
/// A simple observer, just overlooking the runtime of the target.
|
/// A simple observer, just overlooking the runtime of the target.
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
pub struct QemuClockObserver {
|
pub struct QemuClockObserver {
|
||||||
name: String,
|
name: String,
|
||||||
last_runtime: i64,
|
last_runtime: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl QemuClockObserver {
|
impl QemuClockObserver {
|
||||||
@ -60,7 +105,7 @@ impl QemuClockObserver {
|
|||||||
|
|
||||||
/// Gets the runtime for the last execution of this target.
|
/// Gets the runtime for the last execution of this target.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn last_runtime(&self) -> i64 {
|
pub fn last_runtime(&self) -> u64 {
|
||||||
self.last_runtime
|
self.last_runtime
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -83,7 +128,7 @@ where
|
|||||||
// } else {
|
// } else {
|
||||||
// println!("Found Metadata");
|
// println!("Found Metadata");
|
||||||
// }
|
// }
|
||||||
println!("Observer Clock: {}",self.last_runtime());
|
// println!("Observer Clock: {}",self.last_runtime());
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -105,15 +150,16 @@ impl Default for QemuClockObserver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//========== Feedback
|
//========== Feedback
|
||||||
|
/// Nop feedback that annotates execution time in the new testcase, if any
|
||||||
/// A [`Feedback`] rewarding increasing the execution cycles on Qemu.
|
/// for this Feedback, the testcase is never interesting (use with an OR)
|
||||||
#[derive(Debug)]
|
/// It decides, if the given [`ClockObserver`] value of a run is interesting.
|
||||||
pub struct QemuClockIncreaseFeedback {
|
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||||
maximum: i64,
|
pub struct ClockFeedback {
|
||||||
last_runtime: i64,
|
exec_time: Option<u64>,
|
||||||
|
name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, S> Feedback<I, S> for QemuClockIncreaseFeedback
|
impl<I, S> Feedback<I, S> for ClockFeedback
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
S: HasClientPerfMonitor,
|
S: HasClientPerfMonitor,
|
||||||
@ -123,6 +169,81 @@ where
|
|||||||
_state: &mut S,
|
_state: &mut S,
|
||||||
_manager: &mut EM,
|
_manager: &mut EM,
|
||||||
_input: &I,
|
_input: &I,
|
||||||
|
observers: &OT,
|
||||||
|
_exit_kind: &ExitKind,
|
||||||
|
) -> Result<bool, Error>
|
||||||
|
where
|
||||||
|
EM: EventFirer<I>,
|
||||||
|
OT: ObserversTuple<I, S>,
|
||||||
|
{
|
||||||
|
// TODO Replace with match_name_type when stable
|
||||||
|
let observer = observers.match_name::<QemuClockObserver>(self.name()).unwrap();
|
||||||
|
self.exec_time = Some(observer.last_runtime());
|
||||||
|
Ok(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Append to the testcase the generated metadata in case of a new corpus item
|
||||||
|
#[inline]
|
||||||
|
fn append_metadata(&mut self, _state: &mut S, testcase: &mut Testcase<I>) -> Result<(), Error> {
|
||||||
|
*testcase.exec_time_mut() = match self.exec_time {
|
||||||
|
Some(s) => Some(Duration::new(0,360*s as u32)),
|
||||||
|
None => None,
|
||||||
|
};
|
||||||
|
self.exec_time = None;
|
||||||
|
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: &I) -> Result<(), Error> {
|
||||||
|
self.exec_time = None;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Named for ClockFeedback {
|
||||||
|
#[inline]
|
||||||
|
fn name(&self) -> &str {
|
||||||
|
self.name.as_str()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ClockFeedback {
|
||||||
|
/// Creates a new [`ClockFeedback`], deciding if the value of a [`TimeObserver`] with the given `name` of a run is interesting.
|
||||||
|
#[must_use]
|
||||||
|
pub fn new(name: &'static str) -> Self {
|
||||||
|
Self {
|
||||||
|
exec_time: None,
|
||||||
|
name: name.to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a new [`ClockFeedback`], deciding if the given [`TimeObserver`] value of a run is interesting.
|
||||||
|
#[must_use]
|
||||||
|
pub fn new_with_observer(observer: &QemuClockObserver) -> Self {
|
||||||
|
Self {
|
||||||
|
exec_time: None,
|
||||||
|
name: observer.name().to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A [`Feedback`] rewarding increasing the execution cycles on Qemu.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct QemuClockIncreaseFeedback {
|
||||||
|
name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I, S> Feedback<I, S> for QemuClockIncreaseFeedback
|
||||||
|
where
|
||||||
|
I: Input,
|
||||||
|
S: HasFeedbackStates + HasClientPerfMonitor,
|
||||||
|
{
|
||||||
|
fn is_interesting<EM, OT>(
|
||||||
|
&mut self,
|
||||||
|
state: &mut S,
|
||||||
|
_manager: &mut EM,
|
||||||
|
_input: &I,
|
||||||
_observers: &OT,
|
_observers: &OT,
|
||||||
_exit_kind: &ExitKind,
|
_exit_kind: &ExitKind,
|
||||||
) -> Result<bool, Error>
|
) -> Result<bool, Error>
|
||||||
@ -132,8 +253,13 @@ where
|
|||||||
{
|
{
|
||||||
let observer = _observers.match_name::<QemuClockObserver>("clock")
|
let observer = _observers.match_name::<QemuClockObserver>("clock")
|
||||||
.expect("QemuClockObserver not found");
|
.expect("QemuClockObserver not found");
|
||||||
if observer.last_runtime() > self.maximum {
|
let clock_state = state
|
||||||
self.maximum = observer.last_runtime();
|
.feedback_states_mut()
|
||||||
|
.match_name_mut::<MaxIcountMetadata>(&self.name)
|
||||||
|
.unwrap();
|
||||||
|
if observer.last_runtime() > clock_state.max_icount_seen {
|
||||||
|
// println!("Clock improving {}",observer.last_runtime());
|
||||||
|
clock_state.max_icount_seen = observer.last_runtime();
|
||||||
return Ok(true);
|
return Ok(true);
|
||||||
}
|
}
|
||||||
Ok(false)
|
Ok(false)
|
||||||
@ -142,7 +268,7 @@ where
|
|||||||
/// Append to the testcase the generated metadata in case of a new corpus item
|
/// Append to the testcase the generated metadata in case of a new corpus item
|
||||||
#[inline]
|
#[inline]
|
||||||
fn append_metadata(&mut self, _state: &mut S, testcase: &mut Testcase<I>) -> Result<(), Error> {
|
fn append_metadata(&mut self, _state: &mut S, testcase: &mut Testcase<I>) -> Result<(), Error> {
|
||||||
testcase.metadata_mut().insert(QemuIcountMetadata{runtime: self.last_runtime});
|
// testcase.metadata_mut().insert(QemuIcountMetadata{runtime: self.last_runtime});
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,20 +283,20 @@ where
|
|||||||
impl Named for QemuClockIncreaseFeedback {
|
impl Named for QemuClockIncreaseFeedback {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn name(&self) -> &str {
|
fn name(&self) -> &str {
|
||||||
"QemuClockFeedback"
|
&self.name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl QemuClockIncreaseFeedback {
|
impl QemuClockIncreaseFeedback {
|
||||||
/// Creates a new [`HitFeedback`]
|
/// Creates a new [`HitFeedback`]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new() -> Self {
|
pub fn new(name: &'static str) -> Self {
|
||||||
Self {maximum: 0, last_runtime: 0}
|
Self {name: String::from(name)}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for QemuClockIncreaseFeedback {
|
impl Default for QemuClockIncreaseFeedback {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::new()
|
Self::new("MaxClock")
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -183,6 +183,8 @@ extern "C" {
|
|||||||
fn libafl_qemu_set_breakpoint(addr: u64) -> i32;
|
fn libafl_qemu_set_breakpoint(addr: u64) -> i32;
|
||||||
#[cfg(feature = "systemmode")]
|
#[cfg(feature = "systemmode")]
|
||||||
fn libafl_qemu_set_native_breakpoint(addr: u64) -> i32;
|
fn libafl_qemu_set_native_breakpoint(addr: u64) -> i32;
|
||||||
|
#[cfg(feature = "systemmode")]
|
||||||
|
fn libafl_qemu_remove_native_breakpoint(addr: u64) -> i32;
|
||||||
fn libafl_qemu_remove_breakpoint(addr: u64) -> i32;
|
fn libafl_qemu_remove_breakpoint(addr: u64) -> i32;
|
||||||
fn libafl_qemu_set_hook(addr: u64, callback: extern "C" fn(u64), val: u64) -> i32;
|
fn libafl_qemu_set_hook(addr: u64, callback: extern "C" fn(u64), val: u64) -> i32;
|
||||||
fn libafl_qemu_remove_hook(addr: u64) -> i32;
|
fn libafl_qemu_remove_hook(addr: u64) -> i32;
|
||||||
@ -200,7 +202,7 @@ extern "C" {
|
|||||||
#[cfg(feature = "systemmode")]
|
#[cfg(feature = "systemmode")]
|
||||||
fn libafl_snapshot_load(name: *const c_char) -> i32;
|
fn libafl_snapshot_load(name: *const c_char) -> i32;
|
||||||
#[cfg(feature = "systemmode")]
|
#[cfg(feature = "systemmode")]
|
||||||
pub fn libafl_get_clock() -> i64;
|
pub fn libafl_get_clock() -> u64;
|
||||||
|
|
||||||
fn strlen(s: *const u8) -> usize;
|
fn strlen(s: *const u8) -> usize;
|
||||||
|
|
||||||
@ -438,6 +440,9 @@ impl Emulator {
|
|||||||
|
|
||||||
pub fn remove_breakpoint(&self, addr: u64) {
|
pub fn remove_breakpoint(&self, addr: u64) {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
#[cfg(feature = "systemmode")]
|
||||||
|
libafl_qemu_remove_native_breakpoint(addr);
|
||||||
|
#[cfg(not(feature = "systemmode"))]
|
||||||
libafl_qemu_remove_breakpoint(addr);
|
libafl_qemu_remove_breakpoint(addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -682,7 +687,7 @@ impl Emulator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "systemmode")]
|
#[cfg(feature = "systemmode")]
|
||||||
pub fn get_ticks(&self) -> i64{
|
pub fn get_ticks(&self) -> u64{
|
||||||
return unsafe { libafl_get_clock() };
|
return unsafe { libafl_get_clock() };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user