Add TypeRefCreator trait (#2065)

* poc

* ai suggestion

* rename this

* aaaa

* fmt

* simplify

* delete blob

* ignore

* fixup?

* some progress on cow-ification

* some more

* clippy fixes, finalise tests

* whoops, missed a spot

* no std compat

* api change: Named now requires alloc feature

* doc fix

* missed a spot

* additional fixes

* libfuzzer fixes

* fix tutorial

* fix

* add

* aa

* fix tutorial

* fix

* Rename

* fix

* aa

* fmt

* aa

---------

Co-authored-by: Addison Crump <addison.crump@cispa.de>
This commit is contained in:
Dongjia "toka" Zhang 2024-04-23 19:03:30 +02:00 committed by GitHub
parent 76a95bc5fd
commit 176659821a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
80 changed files with 810 additions and 648 deletions

7
.gitignore vendored
View File

@ -68,3 +68,10 @@ libafl_nyx/packer
*.ll *.ll
*.tar.gz *.tar.gz
# common harness names
harness
program
fuzzer
fuzzer_libpng*
forkserver_simple

View File

@ -31,7 +31,7 @@ As you can see from the forkserver example,
let mut shmem = StdShMemProvider::new().unwrap().new_shmem(MAP_SIZE).unwrap(); let mut shmem = StdShMemProvider::new().unwrap().new_shmem(MAP_SIZE).unwrap();
//let the forkserver know the shmid //let the forkserver know the shmid
shmem.write_to_env("__AFL_SHM_ID").unwrap(); shmem.write_to_env("__AFL_SHM_ID").unwrap();
let mut shmem_buf = shmem.as_mut_slice(); let mut shmem_buf = shmem.as_slice_mut();
``` ```
Here we make a shared memory region; `shmem`, and write this to environmental variable `__AFL_SHM_ID`. Then the instrumented binary, or the forkserver, finds this shared memory region (from the aforementioned env var) to record its coverage. On your fuzzer side, you can pass this shmem map to your `Observer` to obtain coverage feedbacks combined with any `Feedback`. Here we make a shared memory region; `shmem`, and write this to environmental variable `__AFL_SHM_ID`. Then the instrumented binary, or the forkserver, finds this shared memory region (from the aforementioned env var) to record its coverage. On your fuzzer side, you can pass this shmem map to your `Observer` to obtain coverage feedbacks combined with any `Feedback`.
@ -59,7 +59,7 @@ let mut shmem;
unsafe{ unsafe{
shmem = StdShMemProvider::new().unwrap().new_shmem(MAX_EDGES_NUM).unwrap(); shmem = StdShMemProvider::new().unwrap().new_shmem(MAX_EDGES_NUM).unwrap();
} }
let shmem_buf = shmem.as_mut_slice(); let shmem_buf = shmem.as_slice_mut();
unsafe{ unsafe{
EDGES_PTR = shmem_buf.as_ptr(); EDGES_PTR = shmem_buf.as_ptr();
} }

View File

@ -22,7 +22,7 @@ use libafl_bolts::{
rands::StdRand, rands::StdRand,
shmem::{unix_shmem, ShMemProvider}, shmem::{unix_shmem, ShMemProvider},
tuples::tuple_list, tuples::tuple_list,
AsMutSlice, AsSlice, AsSlice, AsSliceMut,
}; };
#[allow(clippy::similar_names)] #[allow(clippy::similar_names)]
@ -30,7 +30,7 @@ pub fn main() {
let mut shmem_provider = unix_shmem::UnixShMemProvider::new().unwrap(); let mut shmem_provider = unix_shmem::UnixShMemProvider::new().unwrap();
let mut signals = shmem_provider.new_shmem(16).unwrap(); let mut signals = shmem_provider.new_shmem(16).unwrap();
let signals_len = signals.as_slice().len(); let signals_len = signals.as_slice().len();
let signals_ptr = signals.as_mut_slice().as_mut_ptr(); let signals_ptr = signals.as_slice_mut().as_mut_ptr();
let signals_set = |idx: usize| { let signals_set = |idx: usize| {
unsafe { write(signals_ptr.add(idx), 1) }; unsafe { write(signals_ptr.add(idx), 1) };

View File

@ -29,7 +29,7 @@ use libafl_bolts::{
rands::StdRand, rands::StdRand,
shmem::{unix_shmem, ShMem, ShMemId, ShMemProvider}, shmem::{unix_shmem, ShMem, ShMemId, ShMemProvider},
tuples::tuple_list, tuples::tuple_list,
AsMutSlice, AsSlice, AsSlice, AsSliceMut,
}; };
#[allow(clippy::similar_names)] #[allow(clippy::similar_names)]
@ -39,7 +39,7 @@ pub fn main() {
let shmem_id = signals.id(); let shmem_id = signals.id();
// Create an observation channel using the signals map // Create an observation channel using the signals map
let observer = unsafe { StdMapObserver::new("signals", signals.as_mut_slice()) }; let observer = unsafe { StdMapObserver::new("signals", signals.as_slice_mut()) };
// Create a stacktrace observer // Create a stacktrace observer
let bt_observer = AsanBacktraceObserver::new("AsanBacktraceObserver"); let bt_observer = AsanBacktraceObserver::new("AsanBacktraceObserver");

View File

@ -25,7 +25,7 @@ use libafl_bolts::{
rands::StdRand, rands::StdRand,
shmem::{ShMem, ShMemProvider}, shmem::{ShMem, ShMemProvider},
tuples::tuple_list, tuples::tuple_list,
AsMutSlice, AsSliceMut,
}; };
#[allow(clippy::similar_names)] #[allow(clippy::similar_names)]
@ -42,7 +42,7 @@ pub fn main() {
let mut shmem = shmem_provider.new_shmem(MAP_SIZE).unwrap(); let mut shmem = shmem_provider.new_shmem(MAP_SIZE).unwrap();
//let the forkserver know the shmid //let the forkserver know the shmid
shmem.write_to_env("__AFL_SHM_ID").unwrap(); shmem.write_to_env("__AFL_SHM_ID").unwrap();
let shmem_map = shmem.as_mut_slice(); let shmem_map = shmem.as_slice_mut();
// Create an observation channel using the signals map // Create an observation channel using the signals map
let edges_observer = HitcountsMapObserver::new(ConstMapObserver::<_, MAP_SIZE>::new( let edges_observer = HitcountsMapObserver::new(ConstMapObserver::<_, MAP_SIZE>::new(

View File

@ -24,7 +24,7 @@ use libafl_bolts::{
rands::StdRand, rands::StdRand,
shmem::{unix_shmem, ShMem, ShMemProvider}, shmem::{unix_shmem, ShMem, ShMemProvider},
tuples::tuple_list, tuples::tuple_list,
AsMutSlice, AsSlice, AsSlice, AsSliceMut,
}; };
#[allow(clippy::similar_names)] #[allow(clippy::similar_names)]
@ -32,7 +32,7 @@ pub fn main() {
let mut shmem_provider = unix_shmem::UnixShMemProvider::new().unwrap(); let mut shmem_provider = unix_shmem::UnixShMemProvider::new().unwrap();
let mut signals = shmem_provider.new_shmem(16).unwrap(); let mut signals = shmem_provider.new_shmem(16).unwrap();
let signals_len = signals.len(); let signals_len = signals.len();
let signals_ptr = signals.as_mut_slice().as_mut_ptr(); let signals_ptr = signals.as_slice_mut().as_mut_ptr();
let mut bt = shmem_provider.new_on_shmem::<Option<u64>>(None).unwrap(); let mut bt = shmem_provider.new_on_shmem::<Option<u64>>(None).unwrap();
let signals_set = |idx: usize| { let signals_set = |idx: usize| {

View File

@ -1,7 +1,7 @@
use core::time::Duration; use core::time::Duration;
use std::path::PathBuf; use std::path::PathBuf;
use clap::{self, Parser}; use clap::Parser;
use libafl::{ use libafl::{
corpus::{Corpus, InMemoryCorpus, OnDiskCorpus}, corpus::{Corpus, InMemoryCorpus, OnDiskCorpus},
events::SimpleEventManager, events::SimpleEventManager,
@ -12,7 +12,7 @@ use libafl::{
inputs::BytesInput, inputs::BytesInput,
monitors::SimpleMonitor, monitors::SimpleMonitor,
mutators::{scheduled::havoc_mutations, tokens_mutations, StdScheduledMutator, Tokens}, mutators::{scheduled::havoc_mutations, tokens_mutations, StdScheduledMutator, Tokens},
observers::{CanTrack, ExplicitTracking, HitcountsMapObserver, StdMapObserver, TimeObserver}, observers::{CanTrack, HitcountsMapObserver, StdMapObserver, TimeObserver},
schedulers::{IndexesLenTimeMinimizerScheduler, QueueScheduler}, schedulers::{IndexesLenTimeMinimizerScheduler, QueueScheduler},
stages::mutational::StdMutationalStage, stages::mutational::StdMutationalStage,
state::{HasCorpus, StdState}, state::{HasCorpus, StdState},
@ -22,10 +22,10 @@ use libafl_bolts::{
current_nanos, current_nanos,
rands::StdRand, rands::StdRand,
shmem::{ShMem, ShMemProvider, UnixShMemProvider}, shmem::{ShMem, ShMemProvider, UnixShMemProvider},
tuples::{tuple_list, MatchName, Merge}, tuples::{tuple_list, MatchNameRef, Merge, Referenceable},
AsMutSlice, Truncate, AsSliceMut, Truncate,
}; };
use libafl_targets::{EDGES_MAP_PTR, EDGES_MAP_SIZE_IN_USE}; use libafl_targets::EDGES_MAP_SIZE_IN_USE;
use nix::sys::signal::Signal; use nix::sys::signal::Signal;
/// The commandline args this fuzzer accepts /// The commandline args this fuzzer accepts
@ -98,7 +98,7 @@ pub fn main() {
let mut shmem = shmem_provider.new_shmem(MAP_SIZE).unwrap(); let mut shmem = shmem_provider.new_shmem(MAP_SIZE).unwrap();
// let the forkserver know the shmid // let the forkserver know the shmid
shmem.write_to_env("__AFL_SHM_ID").unwrap(); shmem.write_to_env("__AFL_SHM_ID").unwrap();
let shmem_buf = shmem.as_mut_slice(); let shmem_buf = shmem.as_slice_mut();
// the next line is not needed // the next line is not needed
// unsafe { EDGES_MAP_PTR = shmem_buf.as_mut_ptr() }; // unsafe { EDGES_MAP_PTR = shmem_buf.as_mut_ptr() };
@ -167,6 +167,8 @@ pub fn main() {
// Create the executor for the forkserver // Create the executor for the forkserver
let args = opt.arguments; let args = opt.arguments;
let observer_ref = edges_observer.type_ref();
let mut tokens = Tokens::new(); let mut tokens = Tokens::new();
let mut executor = ForkserverExecutor::builder() let mut executor = ForkserverExecutor::builder()
.program(opt.executable) .program(opt.executable)
@ -183,7 +185,7 @@ pub fn main() {
if let Some(dynamic_map_size) = executor.coverage_map_size() { if let Some(dynamic_map_size) = executor.coverage_map_size() {
executor executor
.observers_mut() .observers_mut()
.match_name_mut::<ExplicitTracking<HitcountsMapObserver<StdMapObserver<'_, u8, false>>, true, false>>("shared_mem") .match_by_ref_mut(observer_ref)
.unwrap() .unwrap()
.as_mut() .as_mut()
.truncate(dynamic_map_size); .truncate(dynamic_map_size);

View File

@ -23,7 +23,7 @@ use libafl_bolts::{
rands::StdRand, rands::StdRand,
shmem::{ShMem, ShMemProvider, UnixShMemProvider}, shmem::{ShMem, ShMemProvider, UnixShMemProvider},
tuples::{tuple_list, MatchName, Merge}, tuples::{tuple_list, MatchName, Merge},
AsMutSlice, Truncate, AsSliceMut, Truncate,
}; };
use nix::sys::signal::Signal; use nix::sys::signal::Signal;
@ -98,7 +98,7 @@ pub fn main() {
let mut shmem = shmem_provider.new_shmem(MAP_SIZE).unwrap(); let mut shmem = shmem_provider.new_shmem(MAP_SIZE).unwrap();
// let the forkserver know the shmid // let the forkserver know the shmid
shmem.write_to_env("__AFL_SHM_ID").unwrap(); shmem.write_to_env("__AFL_SHM_ID").unwrap();
let shmem_buf = shmem.as_mut_slice(); let shmem_buf = shmem.as_slice_mut();
// Create an observation channel using the signals map // Create an observation channel using the signals map
let edges_observer = unsafe { let edges_observer = unsafe {

View File

@ -43,7 +43,7 @@ use libafl_bolts::{
rands::StdRand, rands::StdRand,
shmem::{ShMemProvider, StdShMemProvider}, shmem::{ShMemProvider, StdShMemProvider},
tuples::{tuple_list, Merge}, tuples::{tuple_list, Merge},
AsMutSlice, AsSlice, AsSlice, AsSliceMut,
}; };
use libafl_qemu::{ use libafl_qemu::{
cmplog::{CmpLogMap, CmpLogObserver, QemuCmpLogChildHelper}, cmplog::{CmpLogMap, CmpLogObserver, QemuCmpLogChildHelper},
@ -209,11 +209,11 @@ fn fuzz(
let mut shmem_provider = StdShMemProvider::new()?; let mut shmem_provider = StdShMemProvider::new()?;
let mut edges_shmem = shmem_provider.new_shmem(EDGES_MAP_SIZE_IN_USE).unwrap(); let mut edges_shmem = shmem_provider.new_shmem(EDGES_MAP_SIZE_IN_USE).unwrap();
let edges = edges_shmem.as_mut_slice(); let edges = edges_shmem.as_slice_mut();
unsafe { EDGES_MAP_PTR = edges.as_mut_ptr() }; unsafe { EDGES_MAP_PTR = edges.as_mut_ptr() };
let mut cmp_shmem = shmem_provider.uninit_on_shmem::<CmpLogMap>().unwrap(); let mut cmp_shmem = shmem_provider.uninit_on_shmem::<CmpLogMap>().unwrap();
let cmplog = cmp_shmem.as_mut_slice(); let cmplog = cmp_shmem.as_slice_mut();
// Beginning of a page should be properly aligned. // Beginning of a page should be properly aligned.
#[allow(clippy::cast_ptr_alignment)] #[allow(clippy::cast_ptr_alignment)]

View File

@ -40,7 +40,7 @@ use libafl_bolts::{
rands::StdRand, rands::StdRand,
shmem::{ShMem, ShMemProvider, UnixShMemProvider}, shmem::{ShMem, ShMemProvider, UnixShMemProvider},
tuples::{tuple_list, Merge}, tuples::{tuple_list, Merge},
AsMutSlice, AsSliceMut,
}; };
use libafl_targets::cmps::AFLppCmpLogMap; use libafl_targets::cmps::AFLppCmpLogMap;
use nix::sys::signal::Signal; use nix::sys::signal::Signal;
@ -245,7 +245,7 @@ fn fuzz(
let mut shmem = shmem_provider.new_shmem(MAP_SIZE).unwrap(); let mut shmem = shmem_provider.new_shmem(MAP_SIZE).unwrap();
// let the forkserver know the shmid // let the forkserver know the shmid
shmem.write_to_env("__AFL_SHM_ID").unwrap(); shmem.write_to_env("__AFL_SHM_ID").unwrap();
let shmem_buf = shmem.as_mut_slice(); let shmem_buf = shmem.as_slice_mut();
// To let know the AFL++ binary that we have a big map // To let know the AFL++ binary that we have a big map
std::env::set_var("AFL_MAP_SIZE", format!("{}", MAP_SIZE)); std::env::set_var("AFL_MAP_SIZE", format!("{}", MAP_SIZE));

View File

@ -38,7 +38,7 @@ use libafl_bolts::{
rands::StdRand, rands::StdRand,
shmem::{ShMem, ShMemProvider, UnixShMemProvider}, shmem::{ShMem, ShMemProvider, UnixShMemProvider},
tuples::{tuple_list, Merge}, tuples::{tuple_list, Merge},
AsMutSlice, AsSliceMut,
}; };
use libafl_targets::{ use libafl_targets::{
cmps::{observers::AFLppCmpLogObserver, stages::AFLppCmplogTracingStage}, cmps::{observers::AFLppCmpLogObserver, stages::AFLppCmplogTracingStage},
@ -246,7 +246,7 @@ fn fuzz(
let mut shmem = shmem_provider.new_shmem(MAP_SIZE).unwrap(); let mut shmem = shmem_provider.new_shmem(MAP_SIZE).unwrap();
// let the forkserver know the shmid // let the forkserver know the shmid
shmem.write_to_env("__AFL_SHM_ID").unwrap(); shmem.write_to_env("__AFL_SHM_ID").unwrap();
let shmem_buf = shmem.as_mut_slice(); let shmem_buf = shmem.as_slice_mut();
// To let know the AFL++ binary that we have a big map // To let know the AFL++ binary that we have a big map
std::env::set_var("AFL_MAP_SIZE", format!("{MAP_SIZE}")); std::env::set_var("AFL_MAP_SIZE", format!("{MAP_SIZE}"));

View File

@ -28,7 +28,7 @@ use libafl::{
serialization_format::{DEFAULT_ENV_NAME, DEFAULT_SIZE}, serialization_format::{DEFAULT_ENV_NAME, DEFAULT_SIZE},
ConcolicObserver, ConcolicObserver,
}, },
TimeObserver, CanTrack, CanTrack, TimeObserver,
}, },
schedulers::{IndexesLenTimeMinimizerScheduler, QueueScheduler}, schedulers::{IndexesLenTimeMinimizerScheduler, QueueScheduler},
stages::{ stages::{
@ -43,7 +43,7 @@ use libafl_bolts::{
rands::StdRand, rands::StdRand,
shmem::{ShMem, ShMemProvider, StdShMemProvider}, shmem::{ShMem, ShMemProvider, StdShMemProvider},
tuples::tuple_list, tuples::tuple_list,
AsMutSlice, AsSlice, Named, AsSliceMut, AsSlice, Named,
}; };
use libafl_targets::{ use libafl_targets::{
libfuzzer_initialize, libfuzzer_test_one_input, std_edges_map_observer, CmpLogObserver, libfuzzer_initialize, libfuzzer_test_one_input, std_edges_map_observer, CmpLogObserver,
@ -206,8 +206,7 @@ fn fuzz(
concolic_shmem.write_to_env(DEFAULT_ENV_NAME).unwrap(); concolic_shmem.write_to_env(DEFAULT_ENV_NAME).unwrap();
// The concolic observer observers the concolic shared memory map. // The concolic observer observers the concolic shared memory map.
let concolic_observer = let concolic_observer = ConcolicObserver::new("concolic", concolic_shmem.as_slice_mut());
ConcolicObserver::new("concolic".to_string(), concolic_shmem.as_mut_slice());
let concolic_observer_name = concolic_observer.name().to_string(); let concolic_observer_name = concolic_observer.name().to_string();

View File

@ -25,7 +25,7 @@ use libafl_bolts::{
rands::StdRand, rands::StdRand,
shmem::{ShMemProvider, StdShMemProvider}, shmem::{ShMemProvider, StdShMemProvider},
tuples::tuple_list, tuples::tuple_list,
AsMutSlice, AsSlice, AsSlice, AsSliceMut,
}; };
use libafl_qemu::{ use libafl_qemu::{
edges::{QemuEdgeCoverageChildHelper, EDGES_MAP_PTR, EDGES_MAP_SIZE_IN_USE}, edges::{QemuEdgeCoverageChildHelper, EDGES_MAP_PTR, EDGES_MAP_SIZE_IN_USE},
@ -159,7 +159,7 @@ pub fn fuzz() -> Result<(), Error> {
}; };
let mut edges_shmem = shmem_provider.new_shmem(EDGES_MAP_SIZE_IN_USE).unwrap(); let mut edges_shmem = shmem_provider.new_shmem(EDGES_MAP_SIZE_IN_USE).unwrap();
let edges = edges_shmem.as_mut_slice(); let edges = edges_shmem.as_slice_mut();
unsafe { EDGES_MAP_PTR = edges.as_mut_ptr() }; unsafe { EDGES_MAP_PTR = edges.as_mut_ptr() };
let edges_observer = unsafe { let edges_observer = unsafe {

View File

@ -1,3 +1,5 @@
use std::borrow::Cow;
use libafl::{ use libafl::{
corpus::Testcase, corpus::Testcase,
events::EventFirer, events::EventFirer,
@ -78,8 +80,9 @@ where
impl Named for PacketLenFeedback { impl Named for PacketLenFeedback {
#[inline] #[inline]
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"PacketLenFeedback" static NAME: Cow<'static, str> = Cow::Borrowed("PacketLenFeedback");
&NAME
} }
} }

View File

@ -1,3 +1,5 @@
use std::borrow::Cow;
use lain::traits::Mutatable; use lain::traits::Mutatable;
use libafl::{ use libafl::{
mutators::{MutationResult, Mutator}, mutators::{MutationResult, Mutator},
@ -28,8 +30,9 @@ where
} }
impl Named for LainMutator { impl Named for LainMutator {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"LainMutator" static NAME: Cow<'static, str> = Cow::Borrowed("LainMutator");
&NAME
} }
} }

View File

@ -2,6 +2,7 @@
//! of your corpus. //! of your corpus.
use alloc::{ use alloc::{
borrow::Cow,
string::{String, ToString}, string::{String, ToString},
vec::Vec, vec::Vec,
}; };
@ -143,7 +144,7 @@ where
manager.fire( manager.fire(
state, state,
Event::UpdateUserStats { Event::UpdateUserStats {
name: "minimisation exec pass".to_string(), name: Cow::from("minimisation exec pass"),
value: UserStats::new(UserStatsValue::Ratio(curr, total), AggregatorOps::None), value: UserStats::new(UserStatsValue::Ratio(curr, total), AggregatorOps::None),
phantom: PhantomData, phantom: PhantomData,
}, },

View File

@ -19,9 +19,7 @@ pub use llmp::*;
#[cfg(feature = "tcp_manager")] #[cfg(feature = "tcp_manager")]
#[allow(clippy::ignored_unit_patterns)] #[allow(clippy::ignored_unit_patterns)]
pub mod tcp; pub mod tcp;
#[cfg(feature = "scalability_introspection")] use alloc::{borrow::Cow, boxed::Box, string::String, vec::Vec};
use alloc::string::ToString;
use alloc::{boxed::Box, string::String, vec::Vec};
use core::{ use core::{
fmt, fmt,
hash::{BuildHasher, Hasher}, hash::{BuildHasher, Hasher},
@ -315,7 +313,7 @@ where
/// New user stats event to monitor. /// New user stats event to monitor.
UpdateUserStats { UpdateUserStats {
/// Custom user monitor name /// Custom user monitor name
name: String, name: Cow<'static, str>,
/// Custom user monitor value /// Custom user monitor value
value: UserStats, value: UserStats,
/// [`PhantomData`] /// [`PhantomData`]
@ -534,7 +532,7 @@ where
self.fire( self.fire(
state, state,
Event::UpdateUserStats { Event::UpdateUserStats {
name: "total imported".to_string(), name: Cow::from("total imported"),
value: UserStats::new( value: UserStats::new(
UserStatsValue::Number( UserStatsValue::Number(
(imported_with_observer + imported_without_observer) as u64, (imported_with_observer + imported_without_observer) as u64,

View File

@ -23,7 +23,7 @@ use libafl_bolts::{
os::{dup2, pipes::Pipe}, os::{dup2, pipes::Pipe},
shmem::{ShMem, ShMemProvider, UnixShMemProvider}, shmem::{ShMem, ShMemProvider, UnixShMemProvider},
tuples::Prepend, tuples::Prepend,
AsMutSlice, AsSlice, Truncate, AsSlice, AsSliceMut, Truncate,
}; };
use nix::{ use nix::{
sys::{ sys::{
@ -714,7 +714,7 @@ impl<'a, SP> ForkserverExecutorBuilder<'a, SP> {
shmem.write_to_env("__AFL_SHM_FUZZ_ID")?; shmem.write_to_env("__AFL_SHM_FUZZ_ID")?;
let size_in_bytes = (self.max_input_size + SHMEM_FUZZ_HDR_SIZE).to_ne_bytes(); let size_in_bytes = (self.max_input_size + SHMEM_FUZZ_HDR_SIZE).to_ne_bytes();
shmem.as_mut_slice()[..4].clone_from_slice(&size_in_bytes[..4]); shmem.as_slice_mut()[..4].clone_from_slice(&size_in_bytes[..4]);
Some(shmem) Some(shmem)
} }
}; };
@ -1122,9 +1122,9 @@ where
} }
let size_in_bytes = size.to_ne_bytes(); let size_in_bytes = size.to_ne_bytes();
// The first four bytes tells the size of the shmem. // The first four bytes tells the size of the shmem.
map.as_mut_slice()[..SHMEM_FUZZ_HDR_SIZE] map.as_slice_mut()[..SHMEM_FUZZ_HDR_SIZE]
.copy_from_slice(&size_in_bytes[..SHMEM_FUZZ_HDR_SIZE]); .copy_from_slice(&size_in_bytes[..SHMEM_FUZZ_HDR_SIZE]);
map.as_mut_slice()[SHMEM_FUZZ_HDR_SIZE..(SHMEM_FUZZ_HDR_SIZE + size)] map.as_slice_mut()[SHMEM_FUZZ_HDR_SIZE..(SHMEM_FUZZ_HDR_SIZE + size)]
.copy_from_slice(&target_bytes.as_slice()[..size]); .copy_from_slice(&target_bytes.as_slice()[..size]);
} else { } else {
self.input_file.write_buf(input.target_bytes().as_slice())?; self.input_file.write_buf(input.target_bytes().as_slice())?;
@ -1228,7 +1228,7 @@ mod tests {
use libafl_bolts::{ use libafl_bolts::{
shmem::{ShMem, ShMemProvider, UnixShMemProvider}, shmem::{ShMem, ShMemProvider, UnixShMemProvider},
tuples::tuple_list, tuples::tuple_list,
AsMutSlice, AsSliceMut,
}; };
use serial_test::serial; use serial_test::serial;
@ -1250,7 +1250,7 @@ mod tests {
let mut shmem = shmem_provider.new_shmem(MAP_SIZE).unwrap(); let mut shmem = shmem_provider.new_shmem(MAP_SIZE).unwrap();
shmem.write_to_env("__AFL_SHM_ID").unwrap(); shmem.write_to_env("__AFL_SHM_ID").unwrap();
let shmem_buf = shmem.as_mut_slice(); let shmem_buf = shmem.as_slice_mut();
let edges_observer = HitcountsMapObserver::new(ConstMapObserver::<_, MAP_SIZE>::new( let edges_observer = HitcountsMapObserver::new(ConstMapObserver::<_, MAP_SIZE>::new(
"shared_mem", "shared_mem",

View File

@ -3,7 +3,7 @@
//! This feedback should be used in combination with another feedback as this feedback always considers testcases //! This feedback should be used in combination with another feedback as this feedback always considers testcases
//! to be not interesting. //! to be not interesting.
//! Requires a [`ConcolicObserver`] to observe the concolic trace. //! Requires a [`ConcolicObserver`] to observe the concolic trace.
use alloc::{borrow::ToOwned, string::String}; use alloc::borrow::Cow;
use core::{fmt::Debug, marker::PhantomData}; use core::{fmt::Debug, marker::PhantomData};
use libafl_bolts::Named; use libafl_bolts::Named;
@ -25,7 +25,7 @@ use crate::{
/// Requires a [`ConcolicObserver`] to observe the concolic trace. /// Requires a [`ConcolicObserver`] to observe the concolic trace.
#[derive(Debug)] #[derive(Debug)]
pub struct ConcolicFeedback<S> { pub struct ConcolicFeedback<S> {
name: String, name: Cow<'static, str>,
phantom: PhantomData<S>, phantom: PhantomData<S>,
} }
@ -35,14 +35,14 @@ impl<S> ConcolicFeedback<S> {
#[must_use] #[must_use]
pub fn from_observer(observer: &ConcolicObserver) -> Self { pub fn from_observer(observer: &ConcolicObserver) -> Self {
Self { Self {
name: observer.name().to_owned(), name: observer.name().clone(),
phantom: PhantomData, phantom: PhantomData,
} }
} }
} }
impl<S> Named for ConcolicFeedback<S> { impl<S> Named for ConcolicFeedback<S> {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
&self.name &self.name
} }
} }

View File

@ -1,7 +1,7 @@
//! Diff Feedback, comparing the content of two observers of the same type. //! Diff Feedback, comparing the content of two observers of the same type.
//! //!
use alloc::string::{String, ToString}; use alloc::borrow::Cow;
use core::{ use core::{
fmt::{self, Debug, Formatter}, fmt::{self, Debug, Formatter},
marker::PhantomData, marker::PhantomData,
@ -53,11 +53,11 @@ where
F: FnMut(&O1, &O2) -> DiffResult, F: FnMut(&O1, &O2) -> DiffResult,
{ {
/// This feedback's name /// This feedback's name
name: String, name: Cow<'static, str>,
/// The first observer to compare against /// The first observer to compare against
o1_name: String, o1_name: Cow<'static, str>,
/// The second observer to compare against /// The second observer to compare against
o2_name: String, o2_name: Cow<'static, str>,
/// The function used to compare the two observers /// The function used to compare the two observers
compare_fn: F, compare_fn: F,
phantomm: PhantomData<(O1, O2, I, S)>, phantomm: PhantomData<(O1, O2, I, S)>,
@ -70,9 +70,9 @@ where
O2: Named, O2: Named,
{ {
/// Create a new [`DiffFeedback`] using two observers and a test function. /// Create a new [`DiffFeedback`] using two observers and a test function.
pub fn new(name: &str, o1: &O1, o2: &O2, compare_fn: F) -> Result<Self, Error> { pub fn new(name: &'static str, o1: &O1, o2: &O2, compare_fn: F) -> Result<Self, Error> {
let o1_name = o1.name().to_string(); let o1_name = o1.name().clone();
let o2_name = o2.name().to_string(); let o2_name = o2.name().clone();
if o1_name == o2_name { if o1_name == o2_name {
Err(Error::illegal_argument(format!( Err(Error::illegal_argument(format!(
"DiffFeedback: observer names must be different (both were {o1_name})" "DiffFeedback: observer names must be different (both were {o1_name})"
@ -81,7 +81,7 @@ where
Ok(Self { Ok(Self {
o1_name, o1_name,
o2_name, o2_name,
name: name.to_string(), name: Cow::from(name),
compare_fn, compare_fn,
phantomm: PhantomData, phantomm: PhantomData,
}) })
@ -115,7 +115,7 @@ where
O1: Named, O1: Named,
O2: Named, O2: Named,
{ {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
&self.name &self.name
} }
} }
@ -172,7 +172,7 @@ where
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use alloc::string::{String, ToString}; use alloc::borrow::Cow;
use core::marker::PhantomData; use core::marker::PhantomData;
use libafl_bolts::{tuples::tuple_list, Named}; use libafl_bolts::{tuples::tuple_list, Named};
@ -188,13 +188,13 @@ mod tests {
#[derive(Debug)] #[derive(Debug)]
struct NopObserver { struct NopObserver {
name: String, name: Cow<'static, str>,
value: bool, value: bool,
} }
impl NopObserver { impl NopObserver {
fn new(name: &str, value: bool) -> Self { fn new(name: &'static str, value: bool) -> Self {
Self { Self {
name: name.to_string(), name: Cow::from(name),
value, value,
} }
} }
@ -206,7 +206,7 @@ mod tests {
} }
} }
impl Named for NopObserver { impl Named for NopObserver {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
&self.name &self.name
} }
} }

View File

@ -1,4 +1,4 @@
use alloc::string::{String, ToString}; use alloc::borrow::Cow;
use core::{fmt::Debug, hash::Hash, marker::PhantomData}; use core::{fmt::Debug, hash::Hash, marker::PhantomData};
use hashbrown::HashSet; use hashbrown::HashSet;
@ -70,8 +70,8 @@ pub struct ListFeedback<T>
where where
T: Hash + Eq, T: Hash + Eq,
{ {
name: String, name: Cow<'static, str>,
observer_name: String, observer_name: Cow<'static, str>,
novelty: HashSet<T>, novelty: HashSet<T>,
phantom: PhantomData<T>, phantom: PhantomData<T>,
} }
@ -151,8 +151,8 @@ where
T: Debug + Serialize + Hash + Eq + DeserializeOwned, T: Debug + Serialize + Hash + Eq + DeserializeOwned,
{ {
#[inline] #[inline]
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
self.name.as_str() &self.name
} }
} }
@ -164,8 +164,8 @@ where
#[must_use] #[must_use]
pub fn new(observer: &ListObserver<T>) -> Self { pub fn new(observer: &ListObserver<T>) -> Self {
Self { Self {
name: observer.name().to_string(), name: observer.name().clone(),
observer_name: observer.name().to_string(), observer_name: observer.name().clone(),
novelty: HashSet::<T>::new(), novelty: HashSet::<T>::new(),
phantom: PhantomData, phantom: PhantomData,
} }

View File

@ -1,9 +1,6 @@
//! Map feedback, maximizing or minimizing maps, for example the afl-style map observer. //! Map feedback, maximizing or minimizing maps, for example the afl-style map observer.
use alloc::{ use alloc::{borrow::Cow, vec::Vec};
string::{String, ToString},
vec::Vec,
};
#[rustversion::nightly] #[rustversion::nightly]
use core::simd::prelude::SimdOrd; use core::simd::prelude::SimdOrd;
use core::{ use core::{
@ -12,7 +9,7 @@ use core::{
ops::{BitAnd, BitOr}, ops::{BitAnd, BitOr},
}; };
use libafl_bolts::{AsIter, AsMutSlice, AsSlice, HasRefCnt, Named}; use libafl_bolts::{AsIter, AsSlice, AsSliceMut, HasRefCnt, Named};
use num_traits::PrimInt; use num_traits::PrimInt;
use serde::{de::DeserializeOwned, Deserialize, Serialize}; use serde::{de::DeserializeOwned, Deserialize, Serialize};
@ -244,11 +241,11 @@ impl AsSlice for MapIndexesMetadata {
} }
} }
impl AsMutSlice for MapIndexesMetadata { impl AsSliceMut for MapIndexesMetadata {
type Entry = usize; type Entry = usize;
/// Convert to a slice /// Convert to a slice
fn as_mut_slice(&mut self) -> &mut [usize] { fn as_slice_mut(&mut self) -> &mut [usize] {
self.list.as_mut_slice() self.list.as_slice_mut()
} }
} }
@ -292,12 +289,12 @@ impl AsSlice for MapNoveltiesMetadata {
} }
} }
impl AsMutSlice for MapNoveltiesMetadata { impl AsSliceMut for MapNoveltiesMetadata {
type Entry = usize; type Entry = usize;
/// Convert to a slice /// Convert to a slice
#[must_use] #[must_use]
fn as_mut_slice(&mut self) -> &mut [usize] { fn as_slice_mut(&mut self) -> &mut [usize] {
self.list.as_mut_slice() self.list.as_slice_mut()
} }
} }
@ -387,11 +384,11 @@ pub struct MapFeedback<C, N, O, R, S, T> {
/// New indexes observed in the last observation /// New indexes observed in the last observation
novelties: Option<Vec<usize>>, novelties: Option<Vec<usize>>,
/// Name identifier of this instance /// Name identifier of this instance
name: String, name: Cow<'static, str>,
/// Name identifier of the observer /// Name identifier of the observer
observer_name: String, observer_name: Cow<'static, str>,
/// Name of the feedback as shown in the `UserStats` /// Name of the feedback as shown in the `UserStats`
stats_name: String, stats_name: Cow<'static, str>,
/// Phantom Data of Reducer /// Phantom Data of Reducer
phantom: PhantomData<(C, N, O, R, S, T)>, phantom: PhantomData<(C, N, O, R, S, T)>,
} }
@ -481,7 +478,7 @@ where
map_state.history_map.resize(len, observer.initial()); map_state.history_map.resize(len, observer.initial());
} }
let history_map = map_state.history_map.as_mut_slice(); let history_map = map_state.history_map.as_slice_mut();
if C::INDICES { if C::INDICES {
let mut indices = Vec::new(); let mut indices = Vec::new();
@ -534,7 +531,7 @@ where
manager.fire( manager.fire(
state, state,
Event::UpdateUserStats { Event::UpdateUserStats {
name: self.stats_name.to_string(), name: self.stats_name.clone(),
value: UserStats::new( value: UserStats::new(
UserStatsValue::Ratio(covered as u64, len as u64), UserStatsValue::Ratio(covered as u64, len as u64),
AggregatorOps::Avg, AggregatorOps::Avg,
@ -671,8 +668,8 @@ where
impl<C, N, O, R, S, T> Named for MapFeedback<C, N, O, R, S, T> { impl<C, N, O, R, S, T> Named for MapFeedback<C, N, O, R, S, T> {
#[inline] #[inline]
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
self.name.as_str() &self.name
} }
} }
@ -682,13 +679,18 @@ where
C: AsRef<O>, C: AsRef<O>,
{ {
#[inline] #[inline]
fn observer_name(&self) -> &str { fn observer_name(&self) -> &Cow<'static, str> {
self.observer_name.as_str() &self.observer_name
} }
} }
fn create_stats_name(name: &str) -> String { #[allow(clippy::ptr_arg)]
name.to_lowercase() fn create_stats_name(name: &Cow<'static, str>) -> Cow<'static, str> {
if name.chars().all(char::is_lowercase) {
name.clone()
} else {
name.to_lowercase().into()
}
} }
impl<C, N, O, R, S, T> MapFeedback<C, N, O, R, S, T> impl<C, N, O, R, S, T> MapFeedback<C, N, O, R, S, T>
@ -707,8 +709,8 @@ where
let map_observer = map_observer.as_ref(); let map_observer = map_observer.as_ref();
Self { Self {
novelties: if C::NOVELTIES { Some(vec![]) } else { None }, novelties: if C::NOVELTIES { Some(vec![]) } else { None },
name: map_observer.name().to_string(), name: map_observer.name().clone(),
observer_name: map_observer.name().to_string(), observer_name: map_observer.name().clone(),
stats_name: create_stats_name(map_observer.name()), stats_name: create_stats_name(map_observer.name()),
phantom: PhantomData, phantom: PhantomData,
} }
@ -719,12 +721,13 @@ where
/// same name and therefore also the same history. /// same name and therefore also the same history.
#[must_use] #[must_use]
pub fn with_name(name: &'static str, map_observer: &C) -> Self { pub fn with_name(name: &'static str, map_observer: &C) -> Self {
let name = Cow::from(name);
let map_observer = map_observer.as_ref(); let map_observer = map_observer.as_ref();
Self { Self {
novelties: if C::NOVELTIES { Some(vec![]) } else { None }, novelties: if C::NOVELTIES { Some(vec![]) } else { None },
name: name.to_string(), observer_name: map_observer.name().clone(),
observer_name: map_observer.name().to_string(), stats_name: create_stats_name(&name),
stats_name: create_stats_name(name), name,
phantom: PhantomData, phantom: PhantomData,
} }
} }

View File

@ -5,6 +5,9 @@
// TODO: make S of Feedback<S> an associated type when specialisation + AT is stable // TODO: make S of Feedback<S> an associated type when specialisation + AT is stable
pub mod map; pub mod map;
use alloc::borrow::Cow;
pub use map::*; pub use map::*;
pub mod differential; pub mod differential;
@ -29,7 +32,6 @@ pub mod transferred;
/// The module for list feedback /// The module for list feedback
pub mod list; pub mod list;
use alloc::string::{String, ToString};
use core::{ use core::{
fmt::{self, Debug, Formatter}, fmt::{self, Debug, Formatter},
marker::PhantomData, marker::PhantomData,
@ -138,7 +140,7 @@ where
/// Has an associated observer name (mostly used to retrieve the observer with `MatchName` from an `ObserverTuple`) /// Has an associated observer name (mostly used to retrieve the observer with `MatchName` from an `ObserverTuple`)
pub trait HasObserverName { pub trait HasObserverName {
/// The name associated with the observer /// The name associated with the observer
fn observer_name(&self) -> &str; fn observer_name(&self) -> &Cow<'static, str>;
} }
/// A combined feedback consisting of multiple [`Feedback`]s /// A combined feedback consisting of multiple [`Feedback`]s
@ -154,7 +156,7 @@ where
pub first: A, pub first: A,
/// Second [`Feedback`] /// Second [`Feedback`]
pub second: B, pub second: B,
name: String, name: Cow<'static, str>,
phantom: PhantomData<(S, FL)>, phantom: PhantomData<(S, FL)>,
} }
@ -165,8 +167,8 @@ where
FL: FeedbackLogic<A, B, S>, FL: FeedbackLogic<A, B, S>,
S: State, S: State,
{ {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
self.name.as_ref() &self.name
} }
} }
@ -179,7 +181,12 @@ where
{ {
/// Create a new combined feedback /// Create a new combined feedback
pub fn new(first: A, second: B) -> Self { pub fn new(first: A, second: B) -> Self {
let name = format!("{} ({},{})", FL::name(), first.name(), second.name()); let name = Cow::from(format!(
"{} ({},{})",
FL::name(),
first.name(),
second.name()
));
Self { Self {
first, first,
second, second,
@ -641,7 +648,7 @@ where
/// The feedback to invert /// The feedback to invert
pub first: A, pub first: A,
/// The name /// The name
name: String, name: Cow<'static, str>,
phantom: PhantomData<S>, phantom: PhantomData<S>,
} }
@ -713,7 +720,7 @@ where
S: State, S: State,
{ {
#[inline] #[inline]
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
&self.name &self.name
} }
} }
@ -725,7 +732,7 @@ where
{ {
/// Creates a new [`NotFeedback`]. /// Creates a new [`NotFeedback`].
pub fn new(first: A) -> Self { pub fn new(first: A) -> Self {
let name = format!("Not({})", first.name()); let name = Cow::from(format!("Not({})", first.name()));
Self { Self {
first, first,
name, name,
@ -839,8 +846,9 @@ where
impl Named for CrashFeedback { impl Named for CrashFeedback {
#[inline] #[inline]
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"CrashFeedback" static NAME: Cow<'static, str> = Cow::Borrowed("CrashFeedback");
&NAME
} }
} }
@ -895,8 +903,9 @@ where
impl Named for TimeoutFeedback { impl Named for TimeoutFeedback {
#[inline] #[inline]
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"TimeoutFeedback" static NAME: Cow<'static, str> = Cow::Borrowed("TimeoutFeedback");
&NAME
} }
} }
@ -922,7 +931,7 @@ pub type TimeoutFeedbackFactory = DefaultFeedbackFactory<TimeoutFeedback>;
/// It decides, if the given [`TimeObserver`] value of a run is interesting. /// It decides, if the given [`TimeObserver`] value of a run is interesting.
#[derive(Serialize, Deserialize, Clone, Debug)] #[derive(Serialize, Deserialize, Clone, Debug)]
pub struct TimeFeedback { pub struct TimeFeedback {
name: String, name: Cow<'static, str>,
} }
impl<S> Feedback<S> for TimeFeedback impl<S> Feedback<S> for TimeFeedback
@ -973,8 +982,8 @@ where
impl Named for TimeFeedback { impl Named for TimeFeedback {
#[inline] #[inline]
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
self.name.as_str() &self.name
} }
} }
@ -983,7 +992,7 @@ impl TimeFeedback {
#[must_use] #[must_use]
pub fn new(name: &'static str) -> Self { pub fn new(name: &'static str) -> Self {
Self { Self {
name: name.to_string(), name: Cow::from(name),
} }
} }
@ -991,7 +1000,7 @@ impl TimeFeedback {
#[must_use] #[must_use]
pub fn with_observer(observer: &TimeObserver) -> Self { pub fn with_observer(observer: &TimeObserver) -> Self {
Self { Self {
name: observer.name().to_string(), name: observer.name().clone(),
} }
} }
} }
@ -1033,8 +1042,9 @@ where
impl Named for ConstFeedback { impl Named for ConstFeedback {
#[inline] #[inline]
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"ConstFeedback" static NAME: Cow<'static, str> = Cow::Borrowed("ConstFeedback");
&NAME
} }
} }

View File

@ -1,5 +1,5 @@
//! Nautilus grammar mutator, see <https://github.com/nautilus-fuzz/nautilus> //! Nautilus grammar mutator, see <https://github.com/nautilus-fuzz/nautilus>
use alloc::string::String; use alloc::{borrow::Cow, string::String};
use core::{fmt::Debug, marker::PhantomData}; use core::{fmt::Debug, marker::PhantomData};
use std::fs::create_dir_all; use std::fs::create_dir_all;
@ -74,8 +74,9 @@ impl<'a, S> NautilusFeedback<'a, S> {
} }
impl<'a, S> Named for NautilusFeedback<'a, S> { impl<'a, S> Named for NautilusFeedback<'a, S> {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"NautilusFeedback" static NAME: Cow<'static, str> = Cow::Borrowed("NautilusFeedback");
&NAME
} }
} }

View File

@ -1,6 +1,6 @@
//! The ``NewHashFeedback`` uses the backtrace hash and a hashset to only keep novel cases //! The ``NewHashFeedback`` uses the backtrace hash and a hashset to only keep novel cases
use alloc::string::{String, ToString}; use alloc::{borrow::Cow, string::ToString};
use std::{fmt::Debug, marker::PhantomData}; use std::{fmt::Debug, marker::PhantomData};
use hashbrown::HashSet; use hashbrown::HashSet;
@ -78,8 +78,8 @@ impl HashSetState<u64> for NewHashFeedbackMetadata {
/// A [`NewHashFeedback`] maintains a hashset of already seen stacktraces and considers interesting unseen ones /// A [`NewHashFeedback`] maintains a hashset of already seen stacktraces and considers interesting unseen ones
#[derive(Serialize, Deserialize, Clone, Debug)] #[derive(Serialize, Deserialize, Clone, Debug)]
pub struct NewHashFeedback<O, S> { pub struct NewHashFeedback<O, S> {
name: String, name: Cow<'static, str>,
observer_name: String, observer_name: Cow<'static, str>,
/// Initial capacity of hash set /// Initial capacity of hash set
capacity: usize, capacity: usize,
o_type: PhantomData<(O, S)>, o_type: PhantomData<(O, S)>,
@ -137,14 +137,14 @@ where
impl<O, S> Named for NewHashFeedback<O, S> { impl<O, S> Named for NewHashFeedback<O, S> {
#[inline] #[inline]
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
&self.name &self.name
} }
} }
impl<O, S> HasObserverName for NewHashFeedback<O, S> { impl<O, S> HasObserverName for NewHashFeedback<O, S> {
#[inline] #[inline]
fn observer_name(&self) -> &str { fn observer_name(&self) -> &Cow<'static, str> {
&self.observer_name &self.observer_name
} }
} }
@ -159,18 +159,6 @@ impl<O, S> NewHashFeedback<O, S>
where where
O: ObserverWithHashField + Named, O: ObserverWithHashField + Named,
{ {
/// Returns a new [`NewHashFeedback`].
/// Setting an observer name that doesn't exist would eventually trigger a panic.
#[must_use]
pub fn with_names(name: &str, observer_name: &str) -> Self {
Self {
name: name.to_string(),
observer_name: observer_name.to_string(),
capacity: DEFAULT_CAPACITY,
o_type: PhantomData,
}
}
/// Returns a new [`NewHashFeedback`]. /// Returns a new [`NewHashFeedback`].
#[must_use] #[must_use]
pub fn new(observer: &O) -> Self { pub fn new(observer: &O) -> Self {
@ -182,8 +170,8 @@ where
#[must_use] #[must_use]
pub fn with_capacity(observer: &O, capacity: usize) -> Self { pub fn with_capacity(observer: &O, capacity: usize) -> Self {
Self { Self {
name: NEWHASHFEEDBACK_PREFIX.to_string() + observer.name(), name: Cow::from(NEWHASHFEEDBACK_PREFIX.to_string() + observer.name()),
observer_name: observer.name().to_string(), observer_name: observer.name().clone(),
capacity, capacity,
o_type: PhantomData, o_type: PhantomData,
} }

View File

@ -1,6 +1,6 @@
//! Feedback and metatadata for stderr and stdout. //! Feedback and metatadata for stderr and stdout.
use alloc::string::{String, ToString}; use alloc::{borrow::Cow, string::String};
use libafl_bolts::{impl_serdeany, Named}; use libafl_bolts::{impl_serdeany, Named};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -28,7 +28,7 @@ impl_serdeany!(StdOutMetadata);
/// is never interesting (use with an OR). /// is never interesting (use with an OR).
#[derive(Serialize, Deserialize, Clone, Debug)] #[derive(Serialize, Deserialize, Clone, Debug)]
pub struct StdOutToMetadataFeedback { pub struct StdOutToMetadataFeedback {
name: String, name: Cow<'static, str>,
} }
impl<S> Feedback<S> for StdOutToMetadataFeedback impl<S> Feedback<S> for StdOutToMetadataFeedback
@ -90,8 +90,8 @@ where
impl Named for StdOutToMetadataFeedback { impl Named for StdOutToMetadataFeedback {
#[inline] #[inline]
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
self.name.as_str() &self.name
} }
} }
@ -99,9 +99,9 @@ impl StdOutToMetadataFeedback {
/// Creates a new [`StdOutToMetadataFeedback`]. The provided `name` is /// Creates a new [`StdOutToMetadataFeedback`]. The provided `name` is
/// used to look up the observer. /// used to look up the observer.
#[must_use] #[must_use]
pub fn new(name: &str) -> Self { pub fn new(name: &'static str) -> Self {
Self { Self {
name: name.to_string(), name: Cow::from(name),
} }
} }
@ -109,7 +109,7 @@ impl StdOutToMetadataFeedback {
#[must_use] #[must_use]
pub fn with_observer(observer: &StdOutObserver) -> Self { pub fn with_observer(observer: &StdOutObserver) -> Self {
Self { Self {
name: observer.name().to_string(), name: observer.name().clone(),
} }
} }
} }
@ -127,7 +127,7 @@ impl_serdeany!(StdErrMetadata);
/// is never interesting (use with an OR). /// is never interesting (use with an OR).
#[derive(Serialize, Deserialize, Clone, Debug)] #[derive(Serialize, Deserialize, Clone, Debug)]
pub struct StdErrToMetadataFeedback { pub struct StdErrToMetadataFeedback {
name: String, name: Cow<'static, str>,
} }
impl<S> Feedback<S> for StdErrToMetadataFeedback impl<S> Feedback<S> for StdErrToMetadataFeedback
@ -189,8 +189,8 @@ where
impl Named for StdErrToMetadataFeedback { impl Named for StdErrToMetadataFeedback {
#[inline] #[inline]
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
self.name.as_str() &self.name
} }
} }
@ -198,9 +198,9 @@ impl StdErrToMetadataFeedback {
/// Creates a new [`StdErrToMetadataFeedback`]. The provided `name` is /// Creates a new [`StdErrToMetadataFeedback`]. The provided `name` is
/// used to look up the observer. /// used to look up the observer.
#[must_use] #[must_use]
pub fn new(name: &str) -> Self { pub fn new(name: &'static str) -> Self {
Self { Self {
name: name.to_string(), name: Cow::from(name),
} }
} }
@ -208,7 +208,7 @@ impl StdErrToMetadataFeedback {
#[must_use] #[must_use]
pub fn with_observer(observer: &StdErrObserver) -> Self { pub fn with_observer(observer: &StdErrObserver) -> Self {
Self { Self {
name: observer.name().to_string(), name: observer.name().clone(),
} }
} }
} }

View File

@ -1,6 +1,8 @@
//! Feedbacks and associated metadata for detecting whether a given testcase was transferred from //! Feedbacks and associated metadata for detecting whether a given testcase was transferred from
//! another node. //! another node.
use alloc::borrow::Cow;
use libafl_bolts::{impl_serdeany, Error, Named}; use libafl_bolts::{impl_serdeany, Error, Named};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -10,7 +12,8 @@ use crate::{
}; };
/// Constant name of the [`TransferringMetadata`]. /// Constant name of the [`TransferringMetadata`].
pub const TRANSFERRED_FEEDBACK_NAME: &str = "transferred_feedback_internal"; pub const TRANSFERRED_FEEDBACK_NAME: Cow<'static, str> =
Cow::Borrowed("transferred_feedback_internal");
/// Metadata which denotes whether we are currently transferring an input. Implementors of /// Metadata which denotes whether we are currently transferring an input. Implementors of
/// multi-node communication systems (like [`crate::events::LlmpEventManager`]) should wrap any /// multi-node communication systems (like [`crate::events::LlmpEventManager`]) should wrap any
@ -37,8 +40,8 @@ impl TransferringMetadata {
pub struct TransferredFeedback; pub struct TransferredFeedback;
impl Named for TransferredFeedback { impl Named for TransferredFeedback {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
TRANSFERRED_FEEDBACK_NAME &TRANSFERRED_FEEDBACK_NAME
} }
} }

View File

@ -16,7 +16,7 @@ use alloc::string::ToString;
pub use prometheus::PrometheusMonitor; pub use prometheus::PrometheusMonitor;
#[cfg(feature = "std")] #[cfg(feature = "std")]
pub mod disk; pub mod disk;
use alloc::{fmt::Debug, string::String, vec::Vec}; use alloc::{borrow::Cow, fmt::Debug, string::String, vec::Vec};
use core::{fmt, fmt::Write, time::Duration}; use core::{fmt, fmt::Write, time::Duration};
#[cfg(feature = "std")] #[cfg(feature = "std")]
@ -158,7 +158,7 @@ pub enum UserStatsValue {
/// A Float value /// A Float value
Float(f64), Float(f64),
/// A `String` /// A `String`
String(String), String(Cow<'static, str>),
/// A ratio of two values /// A ratio of two values
Ratio(u64, u64), Ratio(u64, u64),
/// Percent /// Percent
@ -364,7 +364,7 @@ pub struct ClientStats {
/// the start time of the client /// the start time of the client
pub start_time: Duration, pub start_time: Duration,
/// User-defined monitor /// User-defined monitor
pub user_monitor: HashMap<String, UserStats>, pub user_monitor: HashMap<Cow<'static, str>, UserStats>,
/// Client performance statistics /// Client performance statistics
#[cfg(feature = "introspection")] #[cfg(feature = "introspection")]
pub introspection_monitor: ClientPerfMonitor, pub introspection_monitor: ClientPerfMonitor,
@ -465,7 +465,11 @@ impl ClientStats {
} }
/// Update the user-defined stat with name and value /// Update the user-defined stat with name and value
pub fn update_user_stats(&mut self, name: String, value: UserStats) -> Option<UserStats> { pub fn update_user_stats(
&mut self,
name: Cow<'static, str>,
value: UserStats,
) -> Option<UserStats> {
self.user_monitor.insert(name, value) self.user_monitor.insert(name, value)
} }

View File

@ -22,7 +22,7 @@
// When using docker, you may need to point prometheus.yml to the docker0 interface or host.docker.internal // When using docker, you may need to point prometheus.yml to the docker0 interface or host.docker.internal
// ==================== // ====================
use alloc::{fmt::Debug, string::String, vec::Vec}; use alloc::{borrow::Cow, fmt::Debug, string::String, vec::Vec};
use core::{fmt, time::Duration}; use core::{fmt, time::Duration};
use std::{ use std::{
sync::{atomic::AtomicU64, Arc}, sync::{atomic::AtomicU64, Arc},
@ -111,42 +111,42 @@ where
self.corpus_count self.corpus_count
.get_or_create(&Labels { .get_or_create(&Labels {
client: sender_id.0, client: sender_id.0,
stat: String::new(), stat: Cow::from(""),
}) })
.set(corpus_size.try_into().unwrap()); .set(corpus_size.try_into().unwrap());
let objective_size = self.objective_size(); let objective_size = self.objective_size();
self.objective_count self.objective_count
.get_or_create(&Labels { .get_or_create(&Labels {
client: sender_id.0, client: sender_id.0,
stat: String::new(), stat: Cow::from(""),
}) })
.set(objective_size.try_into().unwrap()); .set(objective_size.try_into().unwrap());
let total_execs = self.total_execs(); let total_execs = self.total_execs();
self.executions self.executions
.get_or_create(&Labels { .get_or_create(&Labels {
client: sender_id.0, client: sender_id.0,
stat: String::new(), stat: Cow::from(""),
}) })
.set(total_execs.try_into().unwrap()); .set(total_execs.try_into().unwrap());
let execs_per_sec = self.execs_per_sec(); let execs_per_sec = self.execs_per_sec();
self.exec_rate self.exec_rate
.get_or_create(&Labels { .get_or_create(&Labels {
client: sender_id.0, client: sender_id.0,
stat: String::new(), stat: Cow::from(""),
}) })
.set(execs_per_sec); .set(execs_per_sec);
let run_time = (current_time() - self.start_time).as_secs(); let run_time = (current_time() - self.start_time).as_secs();
self.runtime self.runtime
.get_or_create(&Labels { .get_or_create(&Labels {
client: sender_id.0, client: sender_id.0,
stat: String::new(), stat: Cow::from(""),
}) })
.set(run_time.try_into().unwrap()); // run time in seconds, which can be converted to a time format by Grafana or similar .set(run_time.try_into().unwrap()); // run time in seconds, which can be converted to a time format by Grafana or similar
let total_clients = self.client_stats_count().try_into().unwrap(); // convert usize to u64 (unlikely that # of clients will be > 2^64 -1...) let total_clients = self.client_stats_count().try_into().unwrap(); // convert usize to u64 (unlikely that # of clients will be > 2^64 -1...)
self.clients_count self.clients_count
.get_or_create(&Labels { .get_or_create(&Labels {
client: sender_id.0, client: sender_id.0,
stat: String::new(), stat: Cow::from(""),
}) })
.set(total_clients); .set(total_clients);
@ -352,7 +352,7 @@ pub async fn serve_metrics(
#[derive(Clone, Hash, PartialEq, Eq, EncodeLabelSet, Debug)] #[derive(Clone, Hash, PartialEq, Eq, EncodeLabelSet, Debug)]
pub struct Labels { pub struct Labels {
client: u32, // sender_id: u32, to differentiate between clients when multiple are spawned. client: u32, // sender_id: u32, to differentiate between clients when multiple are spawned.
stat: String, // for custom_stat filtering. stat: Cow<'static, str>, // for custom_stat filtering.
} }
#[derive(Clone)] #[derive(Clone)]

View File

@ -1,6 +1,6 @@
//! Monitor based on ratatui //! Monitor based on ratatui
use alloc::{boxed::Box, string::ToString}; use alloc::{borrow::Cow, boxed::Box, string::ToString};
use core::cmp; use core::cmp;
use std::{ use std::{
collections::VecDeque, collections::VecDeque,
@ -211,7 +211,7 @@ pub struct ClientTuiContext {
pub process_timing: ProcessTiming, pub process_timing: ProcessTiming,
pub item_geometry: ItemGeometry, pub item_geometry: ItemGeometry,
pub user_stats: HashMap<String, UserStats>, pub user_stats: HashMap<Cow<'static, str>, UserStats>,
} }
impl ClientTuiContext { impl ClientTuiContext {

View File

@ -1,6 +1,6 @@
//! Mutations for [`EncodedInput`]s //! Mutations for [`EncodedInput`]s
//! //!
use alloc::vec::Vec; use alloc::{borrow::Cow, vec::Vec};
use core::cmp::{max, min}; use core::cmp::{max, min};
use libafl_bolts::{ use libafl_bolts::{
@ -37,8 +37,9 @@ impl<S: HasRand> Mutator<EncodedInput, S> for EncodedRandMutator {
} }
impl Named for EncodedRandMutator { impl Named for EncodedRandMutator {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"EncodedRandMutator" static NAME: Cow<'static, str> = Cow::Borrowed("EncodedRandMutator");
&NAME
} }
} }
@ -67,8 +68,9 @@ impl<S: HasRand> Mutator<EncodedInput, S> for EncodedIncMutator {
} }
impl Named for EncodedIncMutator { impl Named for EncodedIncMutator {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"EncodedIncMutator" static NAME: Cow<'static, str> = Cow::Borrowed("EncodedIncMutator");
&NAME
} }
} }
@ -97,8 +99,9 @@ impl<S: HasRand> Mutator<EncodedInput, S> for EncodedDecMutator {
} }
impl Named for EncodedDecMutator { impl Named for EncodedDecMutator {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"EncodedDecMutator" static NAME: Cow<'static, str> = Cow::Borrowed("EncodedDecMutator");
&NAME
} }
} }
@ -131,8 +134,9 @@ impl<S: HasRand> Mutator<EncodedInput, S> for EncodedAddMutator {
} }
impl Named for EncodedAddMutator { impl Named for EncodedAddMutator {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"EncodedAddMutator" static NAME: Cow<'static, str> = Cow::Borrowed("EncodedAddMutator");
&NAME
} }
} }
@ -164,8 +168,9 @@ impl<S: HasRand> Mutator<EncodedInput, S> for EncodedDeleteMutator {
} }
impl Named for EncodedDeleteMutator { impl Named for EncodedDeleteMutator {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"EncodedDeleteMutator" static NAME: Cow<'static, str> = Cow::Borrowed("EncodedDeleteMutator");
&NAME
} }
} }
@ -224,8 +229,9 @@ where
} }
impl Named for EncodedInsertCopyMutator { impl Named for EncodedInsertCopyMutator {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"EncodedInsertCopyMutator" static NAME: Cow<'static, str> = Cow::Borrowed("EncodedInsertCopyMutator");
&NAME
} }
} }
@ -261,8 +267,9 @@ impl<S: HasRand> Mutator<EncodedInput, S> for EncodedCopyMutator {
} }
impl Named for EncodedCopyMutator { impl Named for EncodedCopyMutator {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"EncodedCopyMutator" static NAME: Cow<'static, str> = Cow::Borrowed("EncodedCopyMutator");
&NAME
} }
} }
@ -330,8 +337,9 @@ where
} }
impl Named for EncodedCrossoverInsertMutator { impl Named for EncodedCrossoverInsertMutator {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"EncodedCrossoverInsertMutator" static NAME: Cow<'static, str> = Cow::Borrowed("EncodedCrossoverInsertMutator");
&NAME
} }
} }
@ -392,8 +400,9 @@ where
} }
impl Named for EncodedCrossoverReplaceMutator { impl Named for EncodedCrossoverReplaceMutator {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"EncodedCrossoverReplaceMutator" static NAME: Cow<'static, str> = Cow::Borrowed("EncodedCrossoverReplaceMutator");
&NAME
} }
} }

View File

@ -1,6 +1,6 @@
//! Gramatron is the rewritten gramatron fuzzer in rust. //! Gramatron is the rewritten gramatron fuzzer in rust.
//! See the original gramatron repo [`Gramatron`](https://github.com/HexHive/Gramatron) for more details. //! See the original gramatron repo [`Gramatron`](https://github.com/HexHive/Gramatron) for more details.
use alloc::vec::Vec; use alloc::{borrow::Cow, vec::Vec};
use core::cmp::max; use core::cmp::max;
use hashbrown::HashMap; use hashbrown::HashMap;
@ -56,8 +56,9 @@ impl<'a, S> Named for GramatronRandomMutator<'a, S>
where where
S: HasRand + HasMetadata, S: HasRand + HasMetadata,
{ {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"GramatronRandomMutator" static NAME: Cow<'static, str> = Cow::Borrowed("GramatronRandomMutator");
&NAME
} }
} }
@ -151,8 +152,9 @@ where
} }
impl Named for GramatronSpliceMutator { impl Named for GramatronSpliceMutator {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"GramatronSpliceMutator" static NAME: Cow<'static, str> = Cow::Borrowed("GramatronSpliceMutator");
&NAME
} }
} }
@ -253,8 +255,9 @@ where
} }
impl Named for GramatronRecursionMutator { impl Named for GramatronRecursionMutator {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"GramatronRecursionMutator" static NAME: Cow<'static, str> = Cow::Borrowed("GramatronRecursionMutator");
&NAME
} }
} }

View File

@ -1,7 +1,7 @@
//! Grimoire is the rewritten grimoire mutator in rust. //! Grimoire is the rewritten grimoire mutator in rust.
//! See the original repo [`Grimoire`](https://github.com/RUB-SysSec/grimoire) for more details. //! See the original repo [`Grimoire`](https://github.com/RUB-SysSec/grimoire) for more details.
use alloc::vec::Vec; use alloc::{borrow::Cow, vec::Vec};
use core::cmp::{max, min}; use core::cmp::{max, min};
use libafl_bolts::{ use libafl_bolts::{
@ -135,8 +135,9 @@ where
} }
impl Named for GrimoireExtensionMutator { impl Named for GrimoireExtensionMutator {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"GrimoireExtensionMutator" static NAME: Cow<'static, str> = Cow::Borrowed("GrimoireExtensionMutator");
&NAME
} }
} }
@ -209,8 +210,9 @@ where
} }
impl Named for GrimoireRecursiveReplacementMutator { impl Named for GrimoireRecursiveReplacementMutator {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"GrimoireRecursiveReplacementMutator" static NAME: Cow<'static, str> = Cow::Borrowed("GrimoireRecursiveReplacementMutator");
&NAME
} }
} }
@ -320,8 +322,9 @@ where
} }
impl Named for GrimoireStringReplacementMutator { impl Named for GrimoireStringReplacementMutator {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"GrimoireStringReplacementMutator" static NAME: Cow<'static, str> = Cow::Borrowed("GrimoireStringReplacementMutator");
&NAME
} }
} }
@ -378,8 +381,9 @@ where
} }
impl Named for GrimoireRandomDeleteMutator { impl Named for GrimoireRandomDeleteMutator {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"GrimoireRandomDeleteMutator" static NAME: Cow<'static, str> = Cow::Borrowed("GrimoireRandomDeleteMutator");
&NAME
} }
} }

View File

@ -394,11 +394,11 @@ impl<I, S> MutatorsTuple<I, S> for Vec<Box<dyn Mutator<I, S>>> {
} }
fn names_reversed(&self) -> Vec<&str> { fn names_reversed(&self) -> Vec<&str> {
self.iter().rev().map(|x| x.name()).collect() self.iter().rev().map(|x| x.name().as_ref()).collect()
} }
fn names(&self) -> Vec<&str> { fn names(&self) -> Vec<&str> {
self.iter().map(|x| x.name()).collect() self.iter().map(|x| x.name().as_ref()).collect()
} }
} }

View File

@ -1,8 +1,5 @@
//! The `MOpt` mutator scheduler, see <https://github.com/puppet-meteor/MOpt-AFL> and <https://www.usenix.org/conference/usenixsecurity19/presentation/lyu> //! The `MOpt` mutator scheduler, see <https://github.com/puppet-meteor/MOpt-AFL> and <https://www.usenix.org/conference/usenixsecurity19/presentation/lyu>
use alloc::{ use alloc::{borrow::Cow, string::ToString, vec::Vec};
string::{String, ToString},
vec::Vec,
};
use core::{ use core::{
fmt::{self, Debug}, fmt::{self, Debug},
marker::PhantomData, marker::PhantomData,
@ -367,7 +364,7 @@ where
MT: MutatorsTuple<I, S>, MT: MutatorsTuple<I, S>,
S: HasRand + HasMetadata + HasCorpus + HasSolutions, S: HasRand + HasMetadata + HasCorpus + HasSolutions,
{ {
name: String, name: Cow<'static, str>,
mode: MOptMode, mode: MOptMode,
finds_before: usize, finds_before: usize,
mutations: MT, mutations: MT,
@ -532,7 +529,7 @@ where
state.add_metadata::<MOpt>(MOpt::new(mutations.len(), swarm_num, rand_seed)?); state.add_metadata::<MOpt>(MOpt::new(mutations.len(), swarm_num, rand_seed)?);
} }
Ok(Self { Ok(Self {
name: format!("StdMOptMutator[{}]", mutations.names().join(",")), name: Cow::from(format!("StdMOptMutator[{}]", mutations.names().join(","))),
mode: MOptMode::Pilotfuzzing, mode: MOptMode::Pilotfuzzing,
finds_before: 0, finds_before: 0,
mutations, mutations,
@ -617,7 +614,7 @@ where
MT: MutatorsTuple<I, S>, MT: MutatorsTuple<I, S>,
S: HasRand + HasMetadata + HasCorpus + HasSolutions, S: HasRand + HasMetadata + HasCorpus + HasSolutions,
{ {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
&self.name &self.name
} }
} }

View File

@ -1,6 +1,9 @@
//! A wide variety of mutations used during fuzzing. //! A wide variety of mutations used during fuzzing.
use alloc::{borrow::ToOwned, vec::Vec}; use alloc::{
borrow::{Cow, ToOwned},
vec::Vec,
};
use core::{cmp::min, marker::PhantomData, mem::size_of, ops::Range}; use core::{cmp::min, marker::PhantomData, mem::size_of, ops::Range};
use libafl_bolts::{rands::Rand, Named}; use libafl_bolts::{rands::Rand, Named};
@ -135,8 +138,9 @@ where
} }
impl Named for BitFlipMutator { impl Named for BitFlipMutator {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"BitFlipMutator" static NAME: Cow<'static, str> = Cow::Borrowed("BitFlipMutator");
&NAME
} }
} }
@ -168,8 +172,9 @@ where
} }
impl Named for ByteFlipMutator { impl Named for ByteFlipMutator {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"ByteFlipMutator" static NAME: Cow<'static, str> = Cow::Borrowed("ByteFlipMutator");
&NAME
} }
} }
@ -202,8 +207,9 @@ where
} }
impl Named for ByteIncMutator { impl Named for ByteIncMutator {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"ByteIncMutator" static NAME: Cow<'static, str> = Cow::Borrowed("ByteIncMutator");
&NAME
} }
} }
@ -236,8 +242,9 @@ where
} }
impl Named for ByteDecMutator { impl Named for ByteDecMutator {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"ByteDecMutator" static NAME: Cow<'static, str> = Cow::Borrowed("ByteDecMutator");
&NAME
} }
} }
@ -270,8 +277,9 @@ where
} }
impl Named for ByteNegMutator { impl Named for ByteNegMutator {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"ByteNegMutator" static NAME: Cow<'static, str> = Cow::Borrowed("ByteNegMutator");
&NAME
} }
} }
@ -304,8 +312,9 @@ where
} }
impl Named for ByteRandMutator { impl Named for ByteRandMutator {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"ByteRandMutator" static NAME: Cow<'static, str> = Cow::Borrowed("ByteRandMutator");
&NAME
} }
} }
@ -364,8 +373,9 @@ macro_rules! add_mutator_impl {
} }
impl Named for $name { impl Named for $name {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
stringify!($name) static NAME: Cow<'static, str> = Cow::Borrowed(stringify!($name));
&NAME
} }
} }
@ -417,8 +427,9 @@ macro_rules! interesting_mutator_impl {
} }
impl Named for $name { impl Named for $name {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
stringify!($name) static NAME: Cow<'static, str> = Cow::Borrowed(stringify!($name));
&NAME
} }
} }
@ -460,8 +471,9 @@ where
} }
impl Named for BytesDeleteMutator { impl Named for BytesDeleteMutator {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"BytesDeleteMutator" static NAME: Cow<'static, str> = Cow::Borrowed("BytesDeleteMutator");
&NAME
} }
} }
@ -506,8 +518,9 @@ where
} }
impl Named for BytesExpandMutator { impl Named for BytesExpandMutator {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"BytesExpandMutator" static NAME: Cow<'static, str> = Cow::Borrowed("BytesExpandMutator");
&NAME
} }
} }
@ -559,8 +572,9 @@ where
} }
impl Named for BytesInsertMutator { impl Named for BytesInsertMutator {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"BytesInsertMutator" static NAME: Cow<'static, str> = Cow::Borrowed("BytesInsertMutator");
&NAME
} }
} }
@ -612,8 +626,9 @@ where
} }
impl Named for BytesRandInsertMutator { impl Named for BytesRandInsertMutator {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"BytesRandInsertMutator" static NAME: Cow<'static, str> = Cow::Borrowed("BytesRandInsertMutator");
&NAME
} }
} }
@ -650,8 +665,9 @@ where
} }
impl Named for BytesSetMutator { impl Named for BytesSetMutator {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"BytesSetMutator" static NAME: Cow<'static, str> = Cow::Borrowed("BytesSetMutator");
&NAME
} }
} }
@ -688,8 +704,9 @@ where
} }
impl Named for BytesRandSetMutator { impl Named for BytesRandSetMutator {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"BytesRandSetMutator" static NAME: Cow<'static, str> = Cow::Borrowed("BytesRandSetMutator");
&NAME
} }
} }
@ -728,8 +745,9 @@ where
} }
impl Named for BytesCopyMutator { impl Named for BytesCopyMutator {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"BytesCopyMutator" static NAME: Cow<'static, str> = Cow::Borrowed("BytesCopyMutator");
&NAME
} }
} }
@ -787,8 +805,9 @@ where
} }
impl Named for BytesInsertCopyMutator { impl Named for BytesInsertCopyMutator {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"BytesInsertCopyMutator" static NAME: Cow<'static, str> = Cow::Borrowed("BytesInsertCopyMutator");
&NAME
} }
} }
@ -990,8 +1009,9 @@ where
} }
impl Named for BytesSwapMutator { impl Named for BytesSwapMutator {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"BytesSwapMutator" static NAME: Cow<'static, str> = Cow::Borrowed("BytesSwapMutator");
&NAME
} }
} }
@ -1082,8 +1102,9 @@ where
} }
impl<I> Named for CrossoverInsertMutator<I> { impl<I> Named for CrossoverInsertMutator<I> {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"CrossoverInsertMutator" static NAME: Cow<'static, str> = Cow::Borrowed("CrossoverInsertMutator");
&NAME
} }
} }
@ -1163,8 +1184,9 @@ where
} }
impl<I> Named for CrossoverReplaceMutator<I> { impl<I> Named for CrossoverReplaceMutator<I> {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"CrossoverReplaceMutator" static NAME: Cow<'static, str> = Cow::Borrowed("CrossoverReplaceMutator");
&NAME
} }
} }
@ -1242,8 +1264,9 @@ where
} }
impl Named for SpliceMutator { impl Named for SpliceMutator {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"SpliceMutator" static NAME: Cow<'static, str> = Cow::Borrowed("SpliceMutator");
&NAME
} }
} }

View File

@ -1,5 +1,6 @@
//! Mutators for the `Nautilus` grammmar fuzzer //! Mutators for the `Nautilus` grammmar fuzzer
use alloc::borrow::Cow;
use core::fmt::Debug; use core::fmt::Debug;
use grammartec::{ use grammartec::{
@ -60,8 +61,9 @@ impl<S> Mutator<NautilusInput, S> for NautilusRandomMutator<'_> {
} }
impl Named for NautilusRandomMutator<'_> { impl Named for NautilusRandomMutator<'_> {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"NautilusRandomMutator" static NAME: Cow<'static, str> = Cow::Borrowed("NautilusRandomMutator");
&NAME
} }
} }
@ -123,8 +125,9 @@ impl<S> Mutator<NautilusInput, S> for NautilusRecursionMutator<'_> {
} }
impl Named for NautilusRecursionMutator<'_> { impl Named for NautilusRecursionMutator<'_> {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"NautilusRecursionMutator" static NAME: Cow<'static, str> = Cow::Borrowed("NautilusRecursionMutator");
&NAME
} }
} }
@ -190,8 +193,9 @@ where
} }
impl Named for NautilusSpliceMutator<'_> { impl Named for NautilusSpliceMutator<'_> {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"NautilusSpliceMutator" static NAME: Cow<'static, str> = Cow::Borrowed("NautilusSpliceMutator");
&NAME
} }
} }

View File

@ -1,6 +1,6 @@
//! The `ScheduledMutator` schedules multiple mutations internally. //! The `ScheduledMutator` schedules multiple mutations internally.
use alloc::{string::String, vec::Vec}; use alloc::{borrow::Cow, vec::Vec};
use core::{ use core::{
fmt::{self, Debug}, fmt::{self, Debug},
marker::PhantomData, marker::PhantomData,
@ -9,7 +9,7 @@ use core::{
use libafl_bolts::{ use libafl_bolts::{
rands::Rand, rands::Rand,
tuples::{tuple_list, tuple_list_type, Merge, NamedTuple}, tuples::{tuple_list, tuple_list_type, Merge, NamedTuple},
AsMutSlice, AsSlice, Named, AsSlice, AsSliceMut, Named,
}; };
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -40,30 +40,30 @@ use crate::{
)] // for SerdeAny )] // for SerdeAny
pub struct LogMutationMetadata { pub struct LogMutationMetadata {
/// A list of logs /// A list of logs
pub list: Vec<String>, pub list: Vec<Cow<'static, str>>,
} }
libafl_bolts::impl_serdeany!(LogMutationMetadata); libafl_bolts::impl_serdeany!(LogMutationMetadata);
impl AsSlice for LogMutationMetadata { impl AsSlice for LogMutationMetadata {
type Entry = String; type Entry = Cow<'static, str>;
#[must_use] #[must_use]
fn as_slice(&self) -> &[String] { fn as_slice(&self) -> &[Cow<'static, str>] {
self.list.as_slice() self.list.as_slice()
} }
} }
impl AsMutSlice for LogMutationMetadata { impl AsSliceMut for LogMutationMetadata {
type Entry = String; type Entry = Cow<'static, str>;
#[must_use] #[must_use]
fn as_mut_slice(&mut self) -> &mut [String] { fn as_slice_mut(&mut self) -> &mut [Cow<'static, str>] {
self.list.as_mut_slice() self.list.as_slice_mut()
} }
} }
impl LogMutationMetadata { impl LogMutationMetadata {
/// Creates new [`struct@LogMutationMetadata`]. /// Creates new [`struct@LogMutationMetadata`].
#[must_use] #[must_use]
pub fn new(list: Vec<String>) -> Self { pub fn new(list: Vec<Cow<'static, str>>) -> Self {
Self { list } Self { list }
} }
} }
@ -113,7 +113,7 @@ where
MT: MutatorsTuple<I, S>, MT: MutatorsTuple<I, S>,
S: HasRand, S: HasRand,
{ {
name: String, name: Cow<'static, str>,
mutations: MT, mutations: MT,
max_stack_pow: u64, max_stack_pow: u64,
phantom: PhantomData<(I, S)>, phantom: PhantomData<(I, S)>,
@ -139,7 +139,7 @@ where
MT: MutatorsTuple<I, S>, MT: MutatorsTuple<I, S>,
S: HasRand, S: HasRand,
{ {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
&self.name &self.name
} }
} }
@ -198,7 +198,10 @@ where
/// Create a new [`StdScheduledMutator`] instance specifying mutations /// Create a new [`StdScheduledMutator`] instance specifying mutations
pub fn new(mutations: MT) -> Self { pub fn new(mutations: MT) -> Self {
StdScheduledMutator { StdScheduledMutator {
name: format!("StdScheduledMutator[{}]", mutations.names().join(", ")), name: Cow::from(format!(
"StdScheduledMutator[{}]",
mutations.names().join(", ")
)),
mutations, mutations,
max_stack_pow: 7, max_stack_pow: 7,
phantom: PhantomData, phantom: PhantomData,
@ -208,7 +211,10 @@ where
/// Create a new [`StdScheduledMutator`] instance specifying mutations and the maximun number of iterations /// Create a new [`StdScheduledMutator`] instance specifying mutations and the maximun number of iterations
pub fn with_max_stack_pow(mutations: MT, max_stack_pow: u64) -> Self { pub fn with_max_stack_pow(mutations: MT, max_stack_pow: u64) -> Self {
StdScheduledMutator { StdScheduledMutator {
name: format!("StdScheduledMutator[{}]", mutations.names().join(", ")), name: Cow::from(format!(
"StdScheduledMutator[{}]",
mutations.names().join(", ")
)),
mutations, mutations,
max_stack_pow, max_stack_pow,
phantom: PhantomData, phantom: PhantomData,
@ -340,7 +346,7 @@ where
S: HasRand + HasCorpus, S: HasRand + HasCorpus,
SM: ScheduledMutator<I, MT, S>, SM: ScheduledMutator<I, MT, S>,
{ {
name: String, name: Cow<'static, str>,
scheduled: SM, scheduled: SM,
mutation_log: Vec<MutationId>, mutation_log: Vec<MutationId>,
phantom: PhantomData<(I, MT, S)>, phantom: PhantomData<(I, MT, S)>,
@ -368,7 +374,7 @@ where
S: HasRand + HasCorpus, S: HasRand + HasCorpus,
SM: ScheduledMutator<I, MT, S>, SM: ScheduledMutator<I, MT, S>,
{ {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
&self.name &self.name
} }
} }
@ -386,9 +392,9 @@ where
fn post_exec(&mut self, state: &mut S, corpus_idx: Option<CorpusId>) -> Result<(), Error> { fn post_exec(&mut self, state: &mut S, corpus_idx: Option<CorpusId>) -> Result<(), Error> {
if let Some(idx) = corpus_idx { if let Some(idx) = corpus_idx {
let mut testcase = (*state.corpus_mut().get(idx)?).borrow_mut(); let mut testcase = (*state.corpus_mut().get(idx)?).borrow_mut();
let mut log = Vec::<String>::new(); let mut log = Vec::<Cow<'static, str>>::new();
while let Some(idx) = self.mutation_log.pop() { while let Some(idx) = self.mutation_log.pop() {
let name = String::from(self.scheduled.mutations().name(idx.0).unwrap()); // TODO maybe return an Error on None let name = self.scheduled.mutations().name(idx.0).unwrap().clone(); // TODO maybe return an Error on None
log.push(name); log.push(name);
} }
let meta = LogMutationMetadata::new(log); let meta = LogMutationMetadata::new(log);
@ -460,7 +466,7 @@ where
/// This mutator logs all mutators. /// This mutator logs all mutators.
pub fn new(scheduled: SM) -> Self { pub fn new(scheduled: SM) -> Self {
Self { Self {
name: format!("LoggerScheduledMutator[{}]", scheduled.name()), name: Cow::from(format!("LoggerScheduledMutator[{}]", scheduled.name())),
scheduled, scheduled,
mutation_log: vec![], mutation_log: vec![],
phantom: PhantomData, phantom: PhantomData,

View File

@ -1,5 +1,5 @@
//! Mutators for preserving string categories, which may be useful for certain targets which are primarily string-oriented. //! Mutators for preserving string categories, which may be useful for certain targets which are primarily string-oriented.
use alloc::vec::Vec; use alloc::{borrow::Cow, vec::Vec};
use core::{ use core::{
cmp::{Ordering, Reverse}, cmp::{Ordering, Reverse},
ops::Range, ops::Range,
@ -271,8 +271,9 @@ fn rand_replace_range<S: HasRand + HasMaxSize, F: Fn(&mut S) -> char>(
pub struct StringCategoryRandMutator; pub struct StringCategoryRandMutator;
impl Named for StringCategoryRandMutator { impl Named for StringCategoryRandMutator {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"string-category-rand" static NAME: Cow<'static, str> = Cow::Borrowed("string-category-rand");
&NAME
} }
} }
@ -329,8 +330,9 @@ where
pub struct StringSubcategoryRandMutator; pub struct StringSubcategoryRandMutator;
impl Named for StringSubcategoryRandMutator { impl Named for StringSubcategoryRandMutator {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"string-subcategory-rand" static NAME: Cow<'static, str> = Cow::Borrowed("string-subcategory-rand");
&NAME
} }
} }
@ -375,8 +377,9 @@ where
pub struct StringCategoryTokenReplaceMutator; pub struct StringCategoryTokenReplaceMutator;
impl Named for StringCategoryTokenReplaceMutator { impl Named for StringCategoryTokenReplaceMutator {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"string-category-token-replace" static NAME: Cow<'static, str> = Cow::Borrowed("string-category-token-replace");
&NAME
} }
} }
@ -434,8 +437,9 @@ where
pub struct StringSubcategoryTokenReplaceMutator; pub struct StringSubcategoryTokenReplaceMutator;
impl Named for StringSubcategoryTokenReplaceMutator { impl Named for StringSubcategoryTokenReplaceMutator {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"string-subcategory-replace" static NAME: Cow<'static, str> = Cow::Borrowed("string-subcategory-replace");
&NAME
} }
} }

View File

@ -1,6 +1,6 @@
//! Tokens are what AFL calls extras or dictionaries. //! Tokens are what AFL calls extras or dictionaries.
//! They may be inserted as part of mutations during fuzzing. //! They may be inserted as part of mutations during fuzzing.
use alloc::vec::Vec; use alloc::{borrow::Cow, vec::Vec};
#[cfg(any(target_os = "linux", target_vendor = "apple"))] #[cfg(any(target_os = "linux", target_vendor = "apple"))]
use core::slice::from_raw_parts; use core::slice::from_raw_parts;
use core::{ use core::{
@ -346,8 +346,9 @@ where
} }
impl Named for TokenInsert { impl Named for TokenInsert {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"TokenInsert" static NAME: Cow<'static, str> = Cow::Borrowed("TokenInsert");
&NAME
} }
} }
@ -404,8 +405,9 @@ where
} }
impl Named for TokenReplace { impl Named for TokenReplace {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"TokenReplace" static NAME: Cow<'static, str> = Cow::Borrowed("TokenReplace");
&NAME
} }
} }
@ -588,8 +590,9 @@ where
} }
impl Named for I2SRandReplace { impl Named for I2SRandReplace {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"I2SRandReplace" static NAME: Cow<'static, str> = Cow::Borrowed("I2SRandReplace");
&NAME
} }
} }
@ -1673,8 +1676,9 @@ where
} }
impl Named for AFLppRedQueen { impl Named for AFLppRedQueen {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"AFLppRedQueen" static NAME: Cow<'static, str> = Cow::Borrowed("AFLppRedQueen");
&NAME
} }
} }

View File

@ -2,7 +2,7 @@
//! Instead of a random mutator for a random amount of iterations, we can run //! Instead of a random mutator for a random amount of iterations, we can run
//! a specific mutator for a specified amount of iterations //! a specific mutator for a specified amount of iterations
use alloc::{string::String, vec::Vec}; use alloc::{borrow::Cow, vec::Vec};
use core::{ use core::{
fmt::{self, Debug}, fmt::{self, Debug},
marker::PhantomData, marker::PhantomData,
@ -85,7 +85,7 @@ where
MT: MutatorsTuple<I, S>, MT: MutatorsTuple<I, S>,
S: HasRand, S: HasRand,
{ {
name: String, name: Cow<'static, str>,
mutations: MT, mutations: MT,
max_stack_pow: u64, max_stack_pow: u64,
phantom: PhantomData<(I, S)>, phantom: PhantomData<(I, S)>,
@ -140,7 +140,7 @@ where
MT: MutatorsTuple<I, S>, MT: MutatorsTuple<I, S>,
S: HasRand, S: HasRand,
{ {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
&self.name &self.name
} }
} }
@ -238,7 +238,7 @@ where
state.add_metadata(TuneableScheduledMutatorMetadata::default()); state.add_metadata(TuneableScheduledMutatorMetadata::default());
} }
TuneableScheduledMutator { TuneableScheduledMutator {
name: format!("TuneableMutator[{}]", mutations.names().join(", ")), name: Cow::from(format!("TuneableMutator[{}]", mutations.names().join(", "))),
mutations, mutations,
max_stack_pow: 7, max_stack_pow: 7,
phantom: PhantomData, phantom: PhantomData,

View File

@ -1,14 +1,11 @@
//! The `CmpObserver` provides access to the logged values of CMP instructions //! The `CmpObserver` provides access to the logged values of CMP instructions
use alloc::{ use alloc::{borrow::Cow, vec::Vec};
string::{String, ToString},
vec::Vec,
};
use core::{fmt::Debug, marker::PhantomData}; use core::{fmt::Debug, marker::PhantomData};
use c2rust_bitfields::BitfieldStruct; use c2rust_bitfields::BitfieldStruct;
use hashbrown::HashMap; use hashbrown::HashMap;
use libafl_bolts::{ownedref::OwnedRefMut, serdeany::SerdeAny, AsMutSlice, AsSlice, Named}; use libafl_bolts::{ownedref::OwnedRefMut, serdeany::SerdeAny, AsSlice, AsSliceMut, Named};
use serde::{de::DeserializeOwned, Deserialize, Serialize}; use serde::{de::DeserializeOwned, Deserialize, Serialize};
use crate::{executors::ExitKind, inputs::UsesInput, observers::Observer, Error, HasMetadata}; use crate::{executors::ExitKind, inputs::UsesInput, observers::Observer, Error, HasMetadata};
@ -95,12 +92,12 @@ impl AsSlice for CmpValuesMetadata {
} }
} }
impl AsMutSlice for CmpValuesMetadata { impl AsSliceMut for CmpValuesMetadata {
type Entry = CmpValues; type Entry = CmpValues;
/// Convert to a slice /// Convert to a slice
#[must_use] #[must_use]
fn as_mut_slice(&mut self) -> &mut [CmpValues] { fn as_slice_mut(&mut self) -> &mut [CmpValues] {
self.list.as_mut_slice() self.list.as_slice_mut()
} }
} }
@ -250,7 +247,7 @@ where
{ {
cmp_map: OwnedRefMut<'a, CM>, cmp_map: OwnedRefMut<'a, CM>,
size: Option<OwnedRefMut<'a, usize>>, size: Option<OwnedRefMut<'a, usize>>,
name: String, name: Cow<'static, str>,
add_meta: bool, add_meta: bool,
data: M::Data, data: M::Data,
phantom: PhantomData<S>, phantom: PhantomData<S>,
@ -313,7 +310,7 @@ where
S: UsesInput + HasMetadata, S: UsesInput + HasMetadata,
M: CmpObserverMetadata<'a, CM>, M: CmpObserverMetadata<'a, CM>,
{ {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
&self.name &self.name
} }
} }
@ -328,7 +325,7 @@ where
#[must_use] #[must_use]
pub fn new(name: &'static str, map: OwnedRefMut<'a, CM>, add_meta: bool) -> Self { pub fn new(name: &'static str, map: OwnedRefMut<'a, CM>, add_meta: bool) -> Self {
Self { Self {
name: name.to_string(), name: Cow::from(name),
size: None, size: None,
cmp_map: map, cmp_map: map,
add_meta, add_meta,
@ -347,7 +344,7 @@ where
data: M::Data, data: M::Data,
) -> Self { ) -> Self {
Self { Self {
name: name.to_string(), name: Cow::from(name),
size: None, size: None,
cmp_map, cmp_map,
add_meta, add_meta,
@ -365,7 +362,7 @@ where
size: OwnedRefMut<'a, usize>, size: OwnedRefMut<'a, usize>,
) -> Self { ) -> Self {
Self { Self {
name: name.to_string(), name: Cow::from(name),
size: Some(size), size: Some(size),
cmp_map, cmp_map,
add_meta, add_meta,
@ -385,7 +382,7 @@ where
size: OwnedRefMut<'a, usize>, size: OwnedRefMut<'a, usize>,
) -> Self { ) -> Self {
Self { Self {
name: name.to_string(), name: Cow::from(name),
size: Some(size), size: Some(size),
cmp_map, cmp_map,
add_meta, add_meta,

View File

@ -1,4 +1,4 @@
use alloc::string::String; use alloc::borrow::Cow;
use libafl_bolts::Named; use libafl_bolts::Named;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -16,7 +16,7 @@ use crate::{
pub struct ConcolicObserver<'map> { pub struct ConcolicObserver<'map> {
#[serde(skip)] #[serde(skip)]
map: &'map [u8], map: &'map [u8],
name: String, name: Cow<'static, str>,
} }
impl<'map, S> Observer<S> for ConcolicObserver<'map> where S: UsesInput {} impl<'map, S> Observer<S> for ConcolicObserver<'map> where S: UsesInput {}
@ -32,7 +32,7 @@ impl<'map> ConcolicObserver<'map> {
} }
impl<'map> Named for ConcolicObserver<'map> { impl<'map> Named for ConcolicObserver<'map> {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
&self.name &self.name
} }
} }
@ -40,7 +40,10 @@ impl<'map> Named for ConcolicObserver<'map> {
impl<'map> ConcolicObserver<'map> { impl<'map> ConcolicObserver<'map> {
/// Creates a new [`ConcolicObserver`] with the given name and memory buffer. /// Creates a new [`ConcolicObserver`] with the given name and memory buffer.
#[must_use] #[must_use]
pub fn new(name: String, map: &'map [u8]) -> Self { pub fn new(name: &'static str, map: &'map [u8]) -> Self {
Self { map, name } Self {
map,
name: Cow::from(name),
}
} }
} }

View File

@ -1,7 +1,4 @@
use alloc::{ use alloc::{borrow::Cow, vec::Vec};
string::{String, ToString},
vec::Vec,
};
use core::fmt::Debug; use core::fmt::Debug;
use libafl_bolts::{ownedref::OwnedMutPtr, Error, Named}; use libafl_bolts::{ownedref::OwnedMutPtr, Error, Named};
@ -17,7 +14,7 @@ pub struct ListObserver<T>
where where
T: Debug + Serialize, T: Debug + Serialize,
{ {
name: String, name: Cow<'static, str>,
/// The list /// The list
list: OwnedMutPtr<Vec<T>>, list: OwnedMutPtr<Vec<T>>,
} }
@ -34,7 +31,7 @@ where
#[must_use] #[must_use]
pub fn new(name: &'static str, list: OwnedMutPtr<Vec<T>>) -> Self { pub fn new(name: &'static str, list: OwnedMutPtr<Vec<T>>) -> Self {
Self { Self {
name: name.to_string(), name: Cow::from(name),
list, list,
} }
} }
@ -67,7 +64,7 @@ impl<T> Named for ListObserver<T>
where where
T: Debug + Serialize + serde::de::DeserializeOwned, T: Debug + Serialize + serde::de::DeserializeOwned,
{ {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
&self.name &self.name
} }
} }

View File

@ -1,9 +1,6 @@
//! The `MapObserver` provides access a map, usually injected into the target //! The `MapObserver` provides access a map, usually injected into the target
use alloc::{ use alloc::{borrow::Cow, vec::Vec};
string::{String, ToString},
vec::Vec,
};
use core::{ use core::{
fmt::Debug, fmt::Debug,
hash::{Hash, Hasher}, hash::{Hash, Hasher},
@ -16,7 +13,7 @@ use core::{
use ahash::RandomState; use ahash::RandomState;
use libafl_bolts::{ use libafl_bolts::{
ownedref::{OwnedMutPtr, OwnedMutSlice}, ownedref::{OwnedMutPtr, OwnedMutSlice},
AsIter, AsIterMut, AsMutSlice, AsSlice, HasLen, Named, Truncate, AsIter, AsIterMut, AsSlice, AsSliceMut, HasLen, Named, Truncate,
}; };
use meminterval::IntervalTree; use meminterval::IntervalTree;
use num_traits::Bounded; use num_traits::Bounded;
@ -181,7 +178,7 @@ impl<T, const ITH: bool, const NTH: bool> Named for ExplicitTracking<T, ITH, NTH
where where
T: Named, T: Named,
{ {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
self.0.name() self.0.name()
} }
} }
@ -532,7 +529,7 @@ where
{ {
map: OwnedMutSlice<'a, T>, map: OwnedMutSlice<'a, T>,
initial: T, initial: T,
name: String, name: Cow<'static, str>,
} }
impl<'a, S, T> Observer<S> for StdMapObserver<'a, T, false> impl<'a, S, T> Observer<S> for StdMapObserver<'a, T, false>
@ -573,8 +570,8 @@ where
T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned, T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned,
{ {
#[inline] #[inline]
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
self.name.as_str() &self.name
} }
} }
@ -626,7 +623,7 @@ where
fn as_iter_mut(&'it mut self) -> Self::IntoIter { fn as_iter_mut(&'it mut self) -> Self::IntoIter {
let cnt = self.usable_count(); let cnt = self.usable_count();
self.as_mut_slice()[..cnt].iter_mut() self.as_slice_mut()[..cnt].iter_mut()
} }
} }
@ -669,7 +666,7 @@ where
fn into_iter(self) -> Self::IntoIter { fn into_iter(self) -> Self::IntoIter {
let cnt = self.usable_count(); let cnt = self.usable_count();
self.as_mut_slice()[..cnt].iter_mut() self.as_slice_mut()[..cnt].iter_mut()
} }
} }
@ -753,7 +750,7 @@ where
#[inline] #[inline]
fn get_mut(&mut self, idx: usize) -> &mut T { fn get_mut(&mut self, idx: usize) -> &mut T {
&mut self.as_mut_slice()[idx] &mut self.as_slice_mut()[idx]
} }
/// Count the set bytes in the map /// Count the set bytes in the map
@ -795,7 +792,7 @@ where
// Normal memset, see https://rust.godbolt.org/z/Trs5hv // Normal memset, see https://rust.godbolt.org/z/Trs5hv
let initial = self.initial(); let initial = self.initial();
let cnt = self.usable_count(); let cnt = self.usable_count();
let map = self.as_mut_slice(); let map = self.as_slice_mut();
for x in &mut map[0..cnt] { for x in &mut map[0..cnt] {
*x = initial; *x = initial;
} }
@ -844,15 +841,15 @@ where
} }
} }
impl<'a, T, const DIFFERENTIAL: bool> AsMutSlice for StdMapObserver<'a, T, DIFFERENTIAL> impl<'a, T, const DIFFERENTIAL: bool> AsSliceMut for StdMapObserver<'a, T, DIFFERENTIAL>
where where
T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug, T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
{ {
type Entry = T; type Entry = T;
#[must_use] #[must_use]
#[inline] #[inline]
fn as_mut_slice(&mut self) -> &mut [T] { fn as_slice_mut(&mut self) -> &mut [T] {
self.map.as_mut_slice() self.map.as_slice_mut()
} }
} }
@ -868,7 +865,7 @@ where
#[must_use] #[must_use]
unsafe fn maybe_differential<S>(name: S, map: &'a mut [T]) -> Self unsafe fn maybe_differential<S>(name: S, map: &'a mut [T]) -> Self
where where
S: Into<String>, S: Into<Cow<'static, str>>,
{ {
let len = map.len(); let len = map.len();
let ptr = map.as_mut_ptr(); let ptr = map.as_mut_ptr();
@ -879,7 +876,7 @@ where
#[must_use] #[must_use]
fn maybe_differential_from_mut_slice<S>(name: S, map: OwnedMutSlice<'a, T>) -> Self fn maybe_differential_from_mut_slice<S>(name: S, map: OwnedMutSlice<'a, T>) -> Self
where where
S: Into<String>, S: Into<Cow<'static, str>>,
{ {
StdMapObserver { StdMapObserver {
name: name.into(), name: name.into(),
@ -892,7 +889,7 @@ where
#[must_use] #[must_use]
fn maybe_differential_owned<S>(name: S, map: Vec<T>) -> Self fn maybe_differential_owned<S>(name: S, map: Vec<T>) -> Self
where where
S: Into<String>, S: Into<Cow<'static, str>>,
{ {
Self { Self {
map: OwnedMutSlice::from(map), map: OwnedMutSlice::from(map),
@ -908,7 +905,7 @@ where
#[must_use] #[must_use]
fn maybe_differential_from_ownedref<S>(name: S, map: OwnedMutSlice<'a, T>) -> Self fn maybe_differential_from_ownedref<S>(name: S, map: OwnedMutSlice<'a, T>) -> Self
where where
S: Into<String>, S: Into<Cow<'static, str>>,
{ {
Self { Self {
map, map,
@ -923,7 +920,7 @@ where
/// Will dereference the `map_ptr` with up to len elements. /// Will dereference the `map_ptr` with up to len elements.
unsafe fn maybe_differential_from_mut_ptr<S>(name: S, map_ptr: *mut T, len: usize) -> Self unsafe fn maybe_differential_from_mut_ptr<S>(name: S, map_ptr: *mut T, len: usize) -> Self
where where
S: Into<String>, S: Into<Cow<'static, str>>,
{ {
Self::maybe_differential_from_mut_slice( Self::maybe_differential_from_mut_slice(
name, name,
@ -959,7 +956,7 @@ where
#[must_use] #[must_use]
pub unsafe fn new<S>(name: S, map: &'a mut [T]) -> Self pub unsafe fn new<S>(name: S, map: &'a mut [T]) -> Self
where where
S: Into<String>, S: Into<Cow<'static, str>>,
{ {
Self::maybe_differential(name, map) Self::maybe_differential(name, map)
} }
@ -967,7 +964,7 @@ where
/// Creates a new [`MapObserver`] from an [`OwnedMutSlice`] /// Creates a new [`MapObserver`] from an [`OwnedMutSlice`]
pub fn from_mut_slice<S>(name: S, map: OwnedMutSlice<'a, T>) -> Self pub fn from_mut_slice<S>(name: S, map: OwnedMutSlice<'a, T>) -> Self
where where
S: Into<String>, S: Into<Cow<'static, str>>,
{ {
Self::maybe_differential_from_mut_slice(name, map) Self::maybe_differential_from_mut_slice(name, map)
} }
@ -976,7 +973,7 @@ where
#[must_use] #[must_use]
pub fn owned<S>(name: S, map: Vec<T>) -> Self pub fn owned<S>(name: S, map: Vec<T>) -> Self
where where
S: Into<String>, S: Into<Cow<'static, str>>,
{ {
Self::maybe_differential_owned(name, map) Self::maybe_differential_owned(name, map)
} }
@ -988,7 +985,7 @@ where
#[must_use] #[must_use]
pub fn from_ownedref<S>(name: S, map: OwnedMutSlice<'a, T>) -> Self pub fn from_ownedref<S>(name: S, map: OwnedMutSlice<'a, T>) -> Self
where where
S: Into<String>, S: Into<Cow<'static, str>>,
{ {
Self::maybe_differential_from_ownedref(name, map) Self::maybe_differential_from_ownedref(name, map)
} }
@ -999,7 +996,7 @@ where
/// Will dereference the `map_ptr` with up to len elements. /// Will dereference the `map_ptr` with up to len elements.
pub unsafe fn from_mut_ptr<S>(name: S, map_ptr: *mut T, len: usize) -> Self pub unsafe fn from_mut_ptr<S>(name: S, map_ptr: *mut T, len: usize) -> Self
where where
S: Into<String>, S: Into<Cow<'static, str>>,
{ {
Self::maybe_differential_from_mut_ptr(name, map_ptr, len) Self::maybe_differential_from_mut_ptr(name, map_ptr, len)
} }
@ -1017,7 +1014,7 @@ where
#[must_use] #[must_use]
pub unsafe fn differential<S>(name: S, map: &'a mut [T]) -> Self pub unsafe fn differential<S>(name: S, map: &'a mut [T]) -> Self
where where
S: Into<String>, S: Into<Cow<'static, str>>,
{ {
Self::maybe_differential(name, map) Self::maybe_differential(name, map)
} }
@ -1026,7 +1023,7 @@ where
#[must_use] #[must_use]
pub fn differential_owned<S>(name: S, map: Vec<T>) -> Self pub fn differential_owned<S>(name: S, map: Vec<T>) -> Self
where where
S: Into<String>, S: Into<Cow<'static, str>>,
{ {
Self::maybe_differential_owned(name, map) Self::maybe_differential_owned(name, map)
} }
@ -1038,7 +1035,7 @@ where
#[must_use] #[must_use]
pub fn differential_from_ownedref<S>(name: S, map: OwnedMutSlice<'a, T>) -> Self pub fn differential_from_ownedref<S>(name: S, map: OwnedMutSlice<'a, T>) -> Self
where where
S: Into<String>, S: Into<Cow<'static, str>>,
{ {
Self::maybe_differential_from_ownedref(name, map) Self::maybe_differential_from_ownedref(name, map)
} }
@ -1049,7 +1046,7 @@ where
/// Will dereference the `map_ptr` with up to len elements. /// Will dereference the `map_ptr` with up to len elements.
pub unsafe fn differential_from_mut_ptr<S>(name: S, map_ptr: *mut T, len: usize) -> Self pub unsafe fn differential_from_mut_ptr<S>(name: S, map_ptr: *mut T, len: usize) -> Self
where where
S: Into<String>, S: Into<Cow<'static, str>>,
{ {
Self::maybe_differential_from_mut_ptr(name, map_ptr, len) Self::maybe_differential_from_mut_ptr(name, map_ptr, len)
} }
@ -1082,7 +1079,7 @@ where
{ {
map: OwnedMutSlice<'a, T>, map: OwnedMutSlice<'a, T>,
initial: T, initial: T,
name: String, name: Cow<'static, str>,
} }
impl<'a, S, T, const N: usize> Observer<S> for ConstMapObserver<'a, T, N> impl<'a, S, T, const N: usize> Observer<S> for ConstMapObserver<'a, T, N>
@ -1102,8 +1099,8 @@ where
T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned, T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned,
{ {
#[inline] #[inline]
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
self.name.as_str() &self.name
} }
} }
@ -1155,7 +1152,7 @@ where
fn as_iter_mut(&'it mut self) -> Self::IntoIter { fn as_iter_mut(&'it mut self) -> Self::IntoIter {
let cnt = self.usable_count(); let cnt = self.usable_count();
self.as_mut_slice()[..cnt].iter_mut() self.as_slice_mut()[..cnt].iter_mut()
} }
} }
@ -1197,7 +1194,7 @@ where
fn into_iter(self) -> Self::IntoIter { fn into_iter(self) -> Self::IntoIter {
let cnt = self.usable_count(); let cnt = self.usable_count();
self.as_mut_slice()[..cnt].iter_mut() self.as_slice_mut()[..cnt].iter_mut()
} }
} }
@ -1285,7 +1282,7 @@ where
#[inline] #[inline]
fn get_mut(&mut self, idx: usize) -> &mut T { fn get_mut(&mut self, idx: usize) -> &mut T {
&mut self.as_mut_slice()[idx] &mut self.as_slice_mut()[idx]
} }
/// Count the set bytes in the map /// Count the set bytes in the map
@ -1317,7 +1314,7 @@ where
// Normal memset, see https://rust.godbolt.org/z/Trs5hv // Normal memset, see https://rust.godbolt.org/z/Trs5hv
let initial = self.initial(); let initial = self.initial();
let cnt = self.usable_count(); let cnt = self.usable_count();
let map = self.as_mut_slice(); let map = self.as_slice_mut();
for x in &mut map[0..cnt] { for x in &mut map[0..cnt] {
*x = initial; *x = initial;
} }
@ -1354,14 +1351,14 @@ where
} }
} }
impl<'a, T, const N: usize> AsMutSlice for ConstMapObserver<'a, T, N> impl<'a, T, const N: usize> AsSliceMut for ConstMapObserver<'a, T, N>
where where
T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug, T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
{ {
type Entry = T; type Entry = T;
#[inline] #[inline]
fn as_mut_slice(&mut self) -> &mut [T] { fn as_slice_mut(&mut self) -> &mut [T] {
self.map.as_mut_slice() self.map.as_slice_mut()
} }
} }
@ -1379,7 +1376,7 @@ where
assert!(map.len() >= N); assert!(map.len() >= N);
Self { Self {
map: OwnedMutSlice::from(map), map: OwnedMutSlice::from(map),
name: name.to_string(), name: Cow::from(name),
initial: T::default(), initial: T::default(),
} }
} }
@ -1391,7 +1388,7 @@ where
let initial = if map.is_empty() { T::default() } else { map[0] }; let initial = if map.is_empty() { T::default() } else { map[0] };
Self { Self {
map: OwnedMutSlice::from(map), map: OwnedMutSlice::from(map),
name: name.to_string(), name: Cow::from(name),
initial, initial,
} }
} }
@ -1403,7 +1400,7 @@ where
pub unsafe fn from_mut_ptr(name: &'static str, map_ptr: *mut T) -> Self { pub unsafe fn from_mut_ptr(name: &'static str, map_ptr: *mut T) -> Self {
ConstMapObserver { ConstMapObserver {
map: OwnedMutSlice::from_raw_parts_mut(map_ptr, N), map: OwnedMutSlice::from_raw_parts_mut(map_ptr, N),
name: name.to_string(), name: Cow::from(name),
initial: T::default(), initial: T::default(),
} }
} }
@ -1420,7 +1417,7 @@ where
map: OwnedMutSlice<'a, T>, map: OwnedMutSlice<'a, T>,
size: OwnedMutPtr<usize>, size: OwnedMutPtr<usize>,
initial: T, initial: T,
name: String, name: Cow<'static, str>,
} }
impl<'a, S, T> Observer<S> for VariableMapObserver<'a, T> impl<'a, S, T> Observer<S> for VariableMapObserver<'a, T>
@ -1447,8 +1444,8 @@ where
T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Bounded + PartialEq, T: Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Bounded + PartialEq,
{ {
#[inline] #[inline]
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
self.name.as_str() &self.name
} }
} }
@ -1504,7 +1501,7 @@ where
fn as_iter_mut(&'it mut self) -> Self::IntoIter { fn as_iter_mut(&'it mut self) -> Self::IntoIter {
let cnt = self.usable_count(); let cnt = self.usable_count();
self.as_mut_slice()[..cnt].iter_mut() self.as_slice_mut()[..cnt].iter_mut()
} }
} }
@ -1550,7 +1547,7 @@ where
fn into_iter(self) -> Self::IntoIter { fn into_iter(self) -> Self::IntoIter {
let cnt = self.usable_count(); let cnt = self.usable_count();
self.as_mut_slice()[..cnt].iter_mut() self.as_slice_mut()[..cnt].iter_mut()
} }
} }
@ -1647,7 +1644,7 @@ where
} }
fn get_mut(&mut self, idx: usize) -> &mut T { fn get_mut(&mut self, idx: usize) -> &mut T {
&mut self.map.as_mut_slice()[idx] &mut self.map.as_slice_mut()[idx]
} }
/// Count the set bytes in the map /// Count the set bytes in the map
@ -1675,7 +1672,7 @@ where
// Normal memset, see https://rust.godbolt.org/z/Trs5hv // Normal memset, see https://rust.godbolt.org/z/Trs5hv
let initial = self.initial(); let initial = self.initial();
let cnt = self.usable_count(); let cnt = self.usable_count();
let map = self.as_mut_slice(); let map = self.as_slice_mut();
for x in &mut map[0..cnt] { for x in &mut map[0..cnt] {
*x = initial; *x = initial;
} }
@ -1722,7 +1719,7 @@ where
} }
} }
impl<'a, T> AsMutSlice for VariableMapObserver<'a, T> impl<'a, T> AsSliceMut for VariableMapObserver<'a, T>
where where
T: 'static T: 'static
+ Default + Default
@ -1736,9 +1733,9 @@ where
{ {
type Entry = T; type Entry = T;
#[inline] #[inline]
fn as_mut_slice(&mut self) -> &mut [T] { fn as_slice_mut(&mut self) -> &mut [T] {
let cnt = self.usable_count(); let cnt = self.usable_count();
&mut self.map.as_mut_slice()[..cnt] &mut self.map.as_slice_mut()[..cnt]
} }
} }
@ -1798,7 +1795,7 @@ where
impl<S, M> Observer<S> for HitcountsMapObserver<M> impl<S, M> Observer<S> for HitcountsMapObserver<M>
where where
M: MapObserver<Entry = u8> + Observer<S> + AsMutSlice<Entry = u8>, M: MapObserver<Entry = u8> + Observer<S> + AsSliceMut<Entry = u8>,
S: UsesInput, S: UsesInput,
{ {
#[inline] #[inline]
@ -1814,7 +1811,7 @@ where
input: &S::Input, input: &S::Input,
exit_kind: &ExitKind, exit_kind: &ExitKind,
) -> Result<(), Error> { ) -> Result<(), Error> {
let map = self.as_mut_slice(); let map = self.as_slice_mut();
let mut len = map.len(); let mut len = map.len();
let align_offset = map.as_ptr().align_offset(size_of::<u16>()); let align_offset = map.as_ptr().align_offset(size_of::<u16>());
@ -1861,7 +1858,7 @@ where
M: Named + Serialize + serde::de::DeserializeOwned, M: Named + Serialize + serde::de::DeserializeOwned,
{ {
#[inline] #[inline]
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
self.base.name() self.base.name()
} }
} }
@ -1964,14 +1961,14 @@ where
} }
} }
impl<M> AsMutSlice for HitcountsMapObserver<M> impl<M> AsSliceMut for HitcountsMapObserver<M>
where where
M: MapObserver + AsMutSlice, M: MapObserver + AsSliceMut,
{ {
type Entry = <M as AsMutSlice>::Entry; type Entry = <M as AsSliceMut>::Entry;
#[inline] #[inline]
fn as_mut_slice(&mut self) -> &mut [Self::Entry] { fn as_slice_mut(&mut self) -> &mut [Self::Entry] {
self.base.as_mut_slice() self.base.as_slice_mut()
} }
} }
@ -2063,7 +2060,7 @@ where
M: DifferentialObserver<OTA, OTB, S> M: DifferentialObserver<OTA, OTB, S>
+ MapObserver<Entry = u8> + MapObserver<Entry = u8>
+ Serialize + Serialize
+ AsMutSlice<Entry = u8>, + AsSliceMut<Entry = u8>,
OTA: ObserversTuple<S>, OTA: ObserversTuple<S>,
OTB: ObserversTuple<S>, OTB: ObserversTuple<S>,
S: UsesInput, S: UsesInput,
@ -2129,7 +2126,7 @@ where
M: Named + Serialize + serde::de::DeserializeOwned, M: Named + Serialize + serde::de::DeserializeOwned,
{ {
#[inline] #[inline]
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
self.base.name() self.base.name()
} }
} }
@ -2235,14 +2232,14 @@ where
} }
} }
impl<M> AsMutSlice for HitcountsIterableMapObserver<M> impl<M> AsSliceMut for HitcountsIterableMapObserver<M>
where where
M: MapObserver + AsMutSlice, M: MapObserver + AsSliceMut,
{ {
type Entry = <M as AsMutSlice>::Entry; type Entry = <M as AsSliceMut>::Entry;
#[inline] #[inline]
fn as_mut_slice(&mut self) -> &mut [Self::Entry] { fn as_slice_mut(&mut self) -> &mut [Self::Entry] {
self.base.as_mut_slice() self.base.as_slice_mut()
} }
} }
@ -2366,7 +2363,7 @@ where
intervals: IntervalTree<usize, usize>, intervals: IntervalTree<usize, usize>,
len: usize, len: usize,
initial: T, initial: T,
name: String, name: Cow<'static, str>,
iter_idx: usize, iter_idx: usize,
} }
@ -2396,8 +2393,8 @@ where
T: 'static + Default + Copy + Serialize + serde::de::DeserializeOwned + Debug, T: 'static + Default + Copy + Serialize + serde::de::DeserializeOwned + Debug,
{ {
#[inline] #[inline]
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
self.name.as_str() &self.name
} }
} }
@ -2472,7 +2469,7 @@ where
let elem = self.intervals.query(idx..=idx).next().unwrap(); let elem = self.intervals.query(idx..=idx).next().unwrap();
let i = *elem.value; let i = *elem.value;
let j = idx - elem.interval.start; let j = idx - elem.interval.start;
&mut self.maps[i].as_mut_slice()[j] &mut self.maps[i].as_slice_mut()[j]
} }
#[inline] #[inline]
@ -2501,7 +2498,7 @@ where
fn reset_map(&mut self) -> Result<(), Error> { fn reset_map(&mut self) -> Result<(), Error> {
let initial = self.initial(); let initial = self.initial();
for map in &mut self.maps { for map in &mut self.maps {
for x in map.as_mut_slice() { for x in map.as_slice_mut() {
*x = initial; *x = initial;
} }
} }
@ -2553,7 +2550,7 @@ where
maps, maps,
intervals, intervals,
len: idx, len: idx,
name: name.to_string(), name: Cow::from(name),
initial: T::default(), initial: T::default(),
iter_idx: 0, iter_idx: 0,
} }
@ -2601,7 +2598,7 @@ where
maps, maps,
intervals, intervals,
len: idx, len: idx,
name: name.to_string(), name: Cow::from(name),
initial: T::default(), initial: T::default(),
iter_idx: 0, iter_idx: 0,
} }
@ -2695,7 +2692,7 @@ where
{ {
map: Vec<T>, map: Vec<T>,
initial: T, initial: T,
name: String, name: Cow<'static, str>,
} }
impl<S, T> Observer<S> for OwnedMapObserver<T> impl<S, T> Observer<S> for OwnedMapObserver<T>
@ -2715,8 +2712,8 @@ where
T: 'static + Default + Copy + Serialize + serde::de::DeserializeOwned, T: 'static + Default + Copy + Serialize + serde::de::DeserializeOwned,
{ {
#[inline] #[inline]
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
self.name.as_str() &self.name
} }
} }
@ -2750,7 +2747,7 @@ where
type IntoIter = IterMut<'it, T>; type IntoIter = IterMut<'it, T>;
fn as_iter_mut(&'it mut self) -> Self::IntoIter { fn as_iter_mut(&'it mut self) -> Self::IntoIter {
self.as_mut_slice().iter_mut() self.as_slice_mut().iter_mut()
} }
} }
@ -2774,7 +2771,7 @@ where
type IntoIter = IterMut<'it, T>; type IntoIter = IterMut<'it, T>;
fn into_iter(self) -> Self::IntoIter { fn into_iter(self) -> Self::IntoIter {
self.as_mut_slice().iter_mut() self.as_slice_mut().iter_mut()
} }
} }
@ -2842,7 +2839,7 @@ where
#[inline] #[inline]
fn get_mut(&mut self, idx: usize) -> &mut T { fn get_mut(&mut self, idx: usize) -> &mut T {
&mut self.as_mut_slice()[idx] &mut self.as_slice_mut()[idx]
} }
/// Count the set bytes in the map /// Count the set bytes in the map
@ -2880,7 +2877,7 @@ where
// Normal memset, see https://rust.godbolt.org/z/Trs5hv // Normal memset, see https://rust.godbolt.org/z/Trs5hv
let initial = self.initial(); let initial = self.initial();
let cnt = self.usable_count(); let cnt = self.usable_count();
let map = self.as_mut_slice(); let map = self.as_slice_mut();
for x in &mut map[0..cnt] { for x in &mut map[0..cnt] {
*x = initial; *x = initial;
} }
@ -2916,15 +2913,15 @@ where
} }
} }
impl<T> AsMutSlice for OwnedMapObserver<T> impl<T> AsSliceMut for OwnedMapObserver<T>
where where
T: 'static + Default + Copy + Serialize + serde::de::DeserializeOwned + Debug, T: 'static + Default + Copy + Serialize + serde::de::DeserializeOwned + Debug,
{ {
type Entry = T; type Entry = T;
#[must_use] #[must_use]
#[inline] #[inline]
fn as_mut_slice(&mut self) -> &mut [T] { fn as_slice_mut(&mut self) -> &mut [T] {
self.map.as_mut_slice() self.map.as_slice_mut()
} }
} }
@ -2938,7 +2935,7 @@ where
let initial = if map.is_empty() { T::default() } else { map[0] }; let initial = if map.is_empty() { T::default() } else { map[0] };
Self { Self {
map, map,
name: name.to_string(), name: Cow::from(name),
initial, initial,
} }
} }

View File

@ -1,6 +1,9 @@
//! Observers give insights about runs of a target, such as coverage, timing, stack depth, and more. //! Observers give insights about runs of a target, such as coverage, timing, stack depth, and more.
pub mod map; pub mod map;
use alloc::borrow::Cow;
pub use map::*; pub use map::*;
pub mod cmp; pub mod cmp;
@ -22,7 +25,6 @@ pub mod value;
/// List observer /// List observer
pub mod list; pub mod list;
use alloc::string::{String, ToString};
use core::{fmt::Debug, time::Duration}; use core::{fmt::Debug, time::Duration};
#[cfg(feature = "std")] #[cfg(feature = "std")]
use std::time::Instant; use std::time::Instant;
@ -410,7 +412,7 @@ where
/// 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 TimeObserver { pub struct TimeObserver {
name: String, name: Cow<'static, str>,
#[cfg(feature = "std")] #[cfg(feature = "std")]
#[serde(with = "instant_serializer")] #[serde(with = "instant_serializer")]
@ -453,7 +455,7 @@ impl TimeObserver {
#[must_use] #[must_use]
pub fn new(name: &'static str) -> Self { pub fn new(name: &'static str) -> Self {
Self { Self {
name: name.to_string(), name: Cow::from(name),
#[cfg(feature = "std")] #[cfg(feature = "std")]
start_time: Instant::now(), start_time: Instant::now(),
@ -513,7 +515,7 @@ where
} }
impl Named for TimeObserver { impl Named for TimeObserver {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
&self.name &self.name
} }
} }

View File

@ -1,13 +1,11 @@
//! the ``StacktraceObserver`` looks up the stacktrace on the execution thread and computes a hash for it for dedupe //! the ``StacktraceObserver`` looks up the stacktrace on the execution thread and computes a hash for it for dedupe
use alloc::{ use alloc::{borrow::Cow, string::String, vec::Vec};
string::{String, ToString},
vec::Vec,
};
#[cfg(feature = "casr")] #[cfg(feature = "casr")]
use std::{ use std::{
collections::hash_map::DefaultHasher, collections::hash_map::DefaultHasher,
hash::{Hash, Hasher}, hash::{Hash, Hasher},
string::ToString,
}; };
use std::{ use std::{
fmt::Debug, fmt::Debug,
@ -83,10 +81,10 @@ pub fn collect_backtrace() -> u64 {
if symbols.len() > 1 { if symbols.len() > 1 {
let symbol = &symbols[0]; let symbol = &symbols[0];
if let Some(name) = symbol.name() { if let Some(name) = symbol.name() {
strace_entry.function = name.as_str().unwrap_or("").to_string(); strace_entry.function = name.as_str().map_or_else(String::new, str::to_string);
} }
if let Some(file) = symbol.filename() { if let Some(file) = symbol.filename() {
strace_entry.debug.file = file.to_str().unwrap_or("").to_string(); strace_entry.debug.file = file.to_string_lossy().to_string();
} }
strace_entry.debug.line = u64::from(symbol.lineno().unwrap_or(0)); strace_entry.debug.line = u64::from(symbol.lineno().unwrap_or(0));
strace_entry.debug.column = u64::from(symbol.colno().unwrap_or(0)); strace_entry.debug.column = u64::from(symbol.colno().unwrap_or(0));
@ -116,7 +114,7 @@ pub enum HarnessType {
#[allow(clippy::unsafe_derive_deserialize)] #[allow(clippy::unsafe_derive_deserialize)]
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct BacktraceObserver<'a> { pub struct BacktraceObserver<'a> {
observer_name: String, observer_name: Cow<'static, str>,
hash: OwnedRefMut<'a, Option<u64>>, hash: OwnedRefMut<'a, Option<u64>>,
harness_type: HarnessType, harness_type: HarnessType,
} }
@ -125,13 +123,16 @@ impl<'a> BacktraceObserver<'a> {
#[cfg(not(feature = "casr"))] #[cfg(not(feature = "casr"))]
/// Creates a new [`BacktraceObserver`] with the given name. /// Creates a new [`BacktraceObserver`] with the given name.
#[must_use] #[must_use]
pub fn new( pub fn new<S>(
observer_name: &str, observer_name: S,
backtrace_hash: OwnedRefMut<'a, Option<u64>>, backtrace_hash: OwnedRefMut<'a, Option<u64>>,
harness_type: HarnessType, harness_type: HarnessType,
) -> Self { ) -> Self
where
S: Into<Cow<'static, str>>,
{
Self { Self {
observer_name: observer_name.to_string(), observer_name: observer_name.into(),
hash: backtrace_hash, hash: backtrace_hash,
harness_type, harness_type,
} }
@ -140,14 +141,17 @@ impl<'a> BacktraceObserver<'a> {
#[cfg(feature = "casr")] #[cfg(feature = "casr")]
/// Creates a new [`BacktraceObserver`] with the given name. /// Creates a new [`BacktraceObserver`] with the given name.
#[must_use] #[must_use]
pub fn new( pub fn new<S>(
observer_name: &str, observer_name: S,
backtrace_hash: OwnedRefMut<'a, Option<u64>>, backtrace_hash: OwnedRefMut<'a, Option<u64>>,
harness_type: HarnessType, harness_type: HarnessType,
) -> Self { ) -> Self
where
S: Into<Cow<'static, str>>,
{
init_ignored_frames!("rust", "cpp", "go"); init_ignored_frames!("rust", "cpp", "go");
Self { Self {
observer_name: observer_name.to_string(), observer_name: observer_name.into(),
hash: backtrace_hash, hash: backtrace_hash,
harness_type, harness_type,
} }
@ -155,7 +159,10 @@ impl<'a> BacktraceObserver<'a> {
/// Creates a new [`BacktraceObserver`] with the given name, owning a new `backtrace_hash` variable. /// Creates a new [`BacktraceObserver`] with the given name, owning a new `backtrace_hash` variable.
#[must_use] #[must_use]
pub fn owned(observer_name: &str, harness_type: HarnessType) -> Self { pub fn owned<S>(observer_name: S, harness_type: HarnessType) -> Self
where
S: Into<Cow<'static, str>>,
{
Self::new(observer_name, OwnedRefMut::owned(None), harness_type) Self::new(observer_name, OwnedRefMut::owned(None), harness_type)
} }
@ -227,7 +234,7 @@ where
} }
impl<'a> Named for BacktraceObserver<'a> { impl<'a> Named for BacktraceObserver<'a> {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
&self.observer_name &self.observer_name
} }
} }
@ -263,7 +270,7 @@ pub fn get_asan_runtime_flags() -> String {
/// An observer looking at the backtrace of target command using ASAN output /// An observer looking at the backtrace of target command using ASAN output
#[derive(Serialize, Deserialize, Debug, Clone)] #[derive(Serialize, Deserialize, Debug, Clone)]
pub struct AsanBacktraceObserver { pub struct AsanBacktraceObserver {
observer_name: String, observer_name: Cow<'static, str>,
hash: Option<u64>, hash: Option<u64>,
} }
@ -271,9 +278,12 @@ impl AsanBacktraceObserver {
#[cfg(not(feature = "casr"))] #[cfg(not(feature = "casr"))]
/// Creates a new [`BacktraceObserver`] with the given name. /// Creates a new [`BacktraceObserver`] with the given name.
#[must_use] #[must_use]
pub fn new(observer_name: &str) -> Self { pub fn new<S>(observer_name: S) -> Self
where
S: Into<Cow<'static, str>>,
{
Self { Self {
observer_name: observer_name.to_string(), observer_name: observer_name.into(),
hash: None, hash: None,
} }
} }
@ -281,10 +291,13 @@ impl AsanBacktraceObserver {
#[cfg(feature = "casr")] #[cfg(feature = "casr")]
/// Creates a new [`BacktraceObserver`] with the given name. /// Creates a new [`BacktraceObserver`] with the given name.
#[must_use] #[must_use]
pub fn new(observer_name: &str) -> Self { pub fn new<S>(observer_name: S) -> Self
where
S: Into<Cow<'static, str>>,
{
init_ignored_frames!("rust", "cpp", "go"); init_ignored_frames!("rust", "cpp", "go");
Self { Self {
observer_name: observer_name.to_string(), observer_name: observer_name.into(),
hash: None, hash: None,
} }
} }
@ -390,7 +403,7 @@ where
} }
impl Named for AsanBacktraceObserver { impl Named for AsanBacktraceObserver {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
&self.observer_name &self.observer_name
} }
} }

View File

@ -2,7 +2,7 @@
//! The executor must explicitly support these observers. //! The executor must explicitly support these observers.
//! For example, they are supported on the [`crate::executors::CommandExecutor`]. //! For example, they are supported on the [`crate::executors::CommandExecutor`].
use alloc::string::String; use alloc::borrow::Cow;
use std::vec::Vec; use std::vec::Vec;
use libafl_bolts::Named; use libafl_bolts::Named;
@ -15,7 +15,7 @@ use crate::{inputs::UsesInput, observers::Observer};
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct StdOutObserver { pub struct StdOutObserver {
/// The name of the observer. /// The name of the observer.
pub name: String, pub name: Cow<'static, str>,
/// The stdout of the target during its last execution. /// The stdout of the target during its last execution.
pub stdout: Option<Vec<u8>>, pub stdout: Option<Vec<u8>>,
} }
@ -24,8 +24,11 @@ pub struct StdOutObserver {
impl StdOutObserver { impl StdOutObserver {
/// Create a new [`StdOutObserver`] with the given name. /// Create a new [`StdOutObserver`] with the given name.
#[must_use] #[must_use]
pub fn new(name: String) -> Self { pub fn new(name: &'static str) -> Self {
Self { name, stdout: None } Self {
name: Cow::from(name),
stdout: None,
}
} }
} }
@ -45,7 +48,7 @@ where
} }
impl Named for StdOutObserver { impl Named for StdOutObserver {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
&self.name &self.name
} }
} }
@ -55,7 +58,7 @@ impl Named for StdOutObserver {
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct StdErrObserver { pub struct StdErrObserver {
/// The name of the observer. /// The name of the observer.
pub name: String, pub name: Cow<'static, str>,
/// The stderr of the target during its last execution. /// The stderr of the target during its last execution.
pub stderr: Option<Vec<u8>>, pub stderr: Option<Vec<u8>>,
} }
@ -64,8 +67,11 @@ pub struct StdErrObserver {
impl StdErrObserver { impl StdErrObserver {
/// Create a new [`StdErrObserver`] with the given name. /// Create a new [`StdErrObserver`] with the given name.
#[must_use] #[must_use]
pub fn new(name: String) -> Self { pub fn new(name: &'static str) -> Self {
Self { name, stderr: None } Self {
name: Cow::from(name),
stderr: None,
}
} }
} }
@ -85,7 +91,7 @@ where
} }
impl Named for StdErrObserver { impl Named for StdErrObserver {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
&self.name &self.name
} }
} }

View File

@ -1,9 +1,6 @@
//! A simple observer with a single value. //! A simple observer with a single value.
use alloc::{ use alloc::{borrow::Cow, boxed::Box};
boxed::Box,
string::{String, ToString},
};
use core::{ use core::{
cell::{Ref, RefCell}, cell::{Ref, RefCell},
fmt::Debug, fmt::Debug,
@ -29,7 +26,7 @@ where
T: Debug + Serialize, T: Debug + Serialize,
{ {
/// The name of this observer. /// The name of this observer.
name: String, name: Cow<'static, str>,
/// The value. /// The value.
pub value: OwnedRef<'a, T>, pub value: OwnedRef<'a, T>,
} }
@ -42,7 +39,7 @@ where
#[must_use] #[must_use]
pub fn new(name: &'static str, value: OwnedRef<'a, T>) -> Self { pub fn new(name: &'static str, value: OwnedRef<'a, T>) -> Self {
Self { Self {
name: name.to_string(), name: Cow::from(name),
value, value,
} }
} }
@ -87,7 +84,7 @@ impl<'a, T> Named for ValueObserver<'a, T>
where where
T: Debug + Serialize + serde::de::DeserializeOwned, T: Debug + Serialize + serde::de::DeserializeOwned,
{ {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
&self.name &self.name
} }
} }
@ -109,7 +106,7 @@ where
T: Debug + Serialize, T: Debug + Serialize,
{ {
/// The name of this observer. /// The name of this observer.
name: String, name: Cow<'static, str>,
/// The value. /// The value.
pub value: OwnedRef<'a, RefCell<T>>, pub value: OwnedRef<'a, RefCell<T>>,
} }
@ -122,7 +119,7 @@ where
#[must_use] #[must_use]
pub fn new(name: &'static str, value: OwnedRef<'a, RefCell<T>>) -> Self { pub fn new(name: &'static str, value: OwnedRef<'a, RefCell<T>>) -> Self {
Self { Self {
name: name.to_string(), name: Cow::from(name),
value, value,
} }
} }
@ -170,7 +167,7 @@ impl<'a, T> Named for RefCellValueObserver<'a, T>
where where
T: Debug + Serialize + serde::de::DeserializeOwned, T: Debug + Serialize + serde::de::DeserializeOwned,
{ {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
&self.name &self.name
} }
} }

View File

@ -4,7 +4,7 @@ use alloc::vec::Vec;
use core::fmt::Debug; use core::fmt::Debug;
use hashbrown::HashMap; use hashbrown::HashMap;
use libafl_bolts::{rands::Rand, AsMutSlice, AsSlice, HasLen, HasRefCnt}; use libafl_bolts::{rands::Rand, AsSlice, AsSliceMut, HasLen, HasRefCnt};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{ use crate::{
@ -42,12 +42,12 @@ impl AsSlice for AccountingIndexesMetadata {
self.list.as_slice() self.list.as_slice()
} }
} }
impl AsMutSlice for AccountingIndexesMetadata { impl AsSliceMut for AccountingIndexesMetadata {
type Entry = usize; type Entry = usize;
/// Convert to a slice /// Convert to a slice
fn as_mut_slice(&mut self) -> &mut [usize] { fn as_slice_mut(&mut self) -> &mut [usize] {
self.list.as_mut_slice() self.list.as_slice_mut()
} }
} }

View File

@ -1,6 +1,7 @@
//! The calibration stage. The fuzzer measures the average exec time and the bitmap size. //! The calibration stage. The fuzzer measures the average exec time and the bitmap size.
use alloc::{ use alloc::{
borrow::Cow,
string::{String, ToString}, string::{String, ToString},
vec::Vec, vec::Vec,
}; };
@ -311,7 +312,7 @@ where
mgr.fire( mgr.fire(
state, state,
Event::UpdateUserStats { Event::UpdateUserStats {
name: "stability".to_string(), name: Cow::from("stability"),
value: UserStats::new( value: UserStats::new(
UserStatsValue::Ratio( UserStatsValue::Ratio(
(map_len - unstable_entries) as u64, (map_len - unstable_entries) as u64,

View File

@ -1,9 +1,5 @@
//! The colorization stage from `colorization()` in afl++ //! The colorization stage from `colorization()` in afl++
use alloc::{ use alloc::{borrow::Cow, collections::binary_heap::BinaryHeap, string::ToString, vec::Vec};
collections::binary_heap::BinaryHeap,
string::{String, ToString},
vec::Vec,
};
use core::{cmp::Ordering, fmt::Debug, marker::PhantomData, ops::Range}; use core::{cmp::Ordering, fmt::Debug, marker::PhantomData, ops::Range};
use libafl_bolts::{rands::Rand, tuples::MatchName, Named}; use libafl_bolts::{rands::Rand, tuples::MatchName, Named};
@ -55,7 +51,7 @@ impl Ord for Earlier {
/// The mutational stage using power schedules /// The mutational stage using power schedules
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct ColorizationStage<C, E, EM, O, Z> { pub struct ColorizationStage<C, E, EM, O, Z> {
map_observer_name: String, map_observer_name: Cow<'static, str>,
#[allow(clippy::type_complexity)] #[allow(clippy::type_complexity)]
phantom: PhantomData<(C, E, EM, O, E, Z)>, phantom: PhantomData<(C, E, EM, O, E, Z)>,
} }
@ -71,7 +67,7 @@ impl<C, E, EM, O, Z> Named for ColorizationStage<C, E, EM, O, Z>
where where
E: UsesState, E: UsesState,
{ {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
&self.map_observer_name &self.map_observer_name
} }
} }
@ -301,7 +297,7 @@ where
/// Creates a new [`ColorizationStage`] /// Creates a new [`ColorizationStage`]
pub fn new(map_observer: &C) -> Self { pub fn new(map_observer: &C) -> Self {
Self { Self {
map_observer_name: map_observer.name().to_string(), map_observer_name: map_observer.name().clone(),
phantom: PhantomData, phantom: PhantomData,
} }
} }

View File

@ -2,7 +2,7 @@
//! and use the results for fuzzer input and mutations. //! and use the results for fuzzer input and mutations.
//! //!
use alloc::string::String; use alloc::{borrow::Cow, string::String};
#[cfg(feature = "concolic_mutation")] #[cfg(feature = "concolic_mutation")]
use alloc::{string::ToString, vec::Vec}; use alloc::{string::ToString, vec::Vec};
#[cfg(feature = "concolic_mutation")] #[cfg(feature = "concolic_mutation")]
@ -47,8 +47,9 @@ where
} }
impl<EM, TE, Z> Named for ConcolicTracingStage<EM, TE, Z> { impl<EM, TE, Z> Named for ConcolicTracingStage<EM, TE, Z> {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"ConcolicTracingStage" static NAME: Cow<'static, str> = Cow::Borrowed("ConcolicTracingStage");
&NAME
} }
} }

View File

@ -1,6 +1,7 @@
//! The tracing stage can trace the target and enrich a [`crate::corpus::Testcase`] with metadata, for example for `CmpLog`. //! The tracing stage can trace the target and enrich a [`crate::corpus::Testcase`] with metadata, for example for `CmpLog`.
use alloc::{ use alloc::{
borrow::Cow,
string::{String, ToString}, string::{String, ToString},
vec::Vec, vec::Vec,
}; };
@ -49,8 +50,9 @@ pub struct GeneralizationStage<C, EM, O, OT, Z> {
} }
impl<C, EM, O, OT, Z> Named for GeneralizationStage<C, EM, O, OT, Z> { impl<C, EM, O, OT, Z> Named for GeneralizationStage<C, EM, O, OT, Z> {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"GeneralizationStage" static NAME: Cow<'static, str> = Cow::Borrowed("GeneralizationStage");
&NAME
} }
} }

View File

@ -4,8 +4,8 @@ A well-known [`Stage`], for example, is the mutational stage, running multiple [
Other stages may enrich [`crate::corpus::Testcase`]s with metadata. Other stages may enrich [`crate::corpus::Testcase`]s with metadata.
*/ */
use alloc::{boxed::Box, vec::Vec}; use alloc::{borrow::Cow, boxed::Box, vec::Vec};
use core::{any, marker::PhantomData}; use core::marker::PhantomData;
pub use calibrate::CalibrationStage; pub use calibrate::CalibrationStage;
pub use colorization::*; pub use colorization::*;
@ -305,8 +305,9 @@ where
CB: FnMut(&mut Z, &mut E, &mut E::State, &mut EM) -> Result<(), Error>, CB: FnMut(&mut Z, &mut E, &mut E::State, &mut EM) -> Result<(), Error>,
E: UsesState, E: UsesState,
{ {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
any::type_name::<Self>() static NAME: Cow<'static, str> = Cow::Borrowed("<unnamed fn>");
&NAME
} }
} }
@ -644,6 +645,7 @@ impl ExecutionCountRestartHelper {
#[cfg(test)] #[cfg(test)]
pub mod test { pub mod test {
use alloc::borrow::Cow;
use core::marker::PhantomData; use core::marker::PhantomData;
use libafl_bolts::{impl_serdeany, Error, Named}; use libafl_bolts::{impl_serdeany, Error, Named};
@ -745,8 +747,9 @@ pub mod test {
struct StageWithOneTry; struct StageWithOneTry;
impl Named for StageWithOneTry { impl Named for StageWithOneTry {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"TestStage" static NAME: Cow<'static, str> = Cow::Borrowed("TestStage");
&NAME
} }
} }

View File

@ -1,7 +1,8 @@
//| The [`MutationalStage`] is the default stage used during fuzzing. //| The [`MutationalStage`] is the default stage used during fuzzing.
//! For the current input, it will perform a range of random mutations, and then run them in the executor. //! For the current input, it will perform a range of random mutations, and then run them in the executor.
use core::{any::type_name, marker::PhantomData}; use alloc::borrow::Cow;
use core::marker::PhantomData;
use libafl_bolts::{rands::Rand, Named}; use libafl_bolts::{rands::Rand, Named};
@ -313,8 +314,9 @@ where
Z: Evaluator<E, EM>, Z: Evaluator<E, EM>,
Z::State: HasCorpus + HasRand, Z::State: HasCorpus + HasRand,
{ {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
type_name::<Self>() static NAME: Cow<'static, str> = Cow::Borrowed("MultiMutational");
&NAME
} }
} }

View File

@ -1,7 +1,7 @@
//! Stage to compute/report AFL stats //! Stage to compute/report AFL stats
#[cfg(feature = "std")] #[cfg(feature = "std")]
use alloc::string::ToString; use alloc::{borrow::Cow, string::ToString};
use core::{marker::PhantomData, time::Duration}; use core::{marker::PhantomData, time::Duration};
use libafl_bolts::current_time; use libafl_bolts::current_time;
@ -109,9 +109,9 @@ where
_manager.fire( _manager.fire(
state, state,
Event::UpdateUserStats { Event::UpdateUserStats {
name: "AflStats".to_string(), name: Cow::from("AflStats"),
value: UserStats::new( value: UserStats::new(
UserStatsValue::String(json.to_string()), UserStatsValue::String(Cow::from(json.to_string())),
AggregatorOps::None, AggregatorOps::None,
), ),
phantom: PhantomData, phantom: PhantomData,

View File

@ -1,5 +1,6 @@
//! The [`SyncFromDiskStage`] is a stage that imports inputs from disk for e.g. sync with AFL //! The [`SyncFromDiskStage`] is a stage that imports inputs from disk for e.g. sync with AFL
use alloc::borrow::Cow;
use core::marker::PhantomData; use core::marker::PhantomData;
use std::{ use std::{
fs, fs,
@ -63,8 +64,9 @@ impl<CB, E, EM, Z> Named for SyncFromDiskStage<CB, E, EM, Z>
where where
E: UsesState, E: UsesState,
{ {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
self.sync_dir.to_str().unwrap() static NAME: Cow<'static, str> = Cow::Borrowed("SyncFromDiskStage");
&NAME
} }
} }

View File

@ -1,6 +1,6 @@
//! The [`TMinMutationalStage`] is a stage which will attempt to minimize corpus entries. //! The [`TMinMutationalStage`] is a stage which will attempt to minimize corpus entries.
use alloc::string::{String, ToString}; use alloc::borrow::Cow;
use core::{borrow::BorrowMut, fmt::Debug, hash::Hash, marker::PhantomData}; use core::{borrow::BorrowMut, fmt::Debug, hash::Hash, marker::PhantomData};
use ahash::RandomState; use ahash::RandomState;
@ -349,33 +349,20 @@ where
/// provided /// provided
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct MapEqualityFeedback<M, S> { pub struct MapEqualityFeedback<M, S> {
name: String, name: Cow<'static, str>,
obs_name: String, obs_name: Cow<'static, str>,
orig_hash: u64, orig_hash: u64,
phantom: PhantomData<(M, S)>, phantom: PhantomData<(M, S)>,
} }
impl<M, S> MapEqualityFeedback<M, S> {
/// Create a new map equality feedback -- can be used with feedback logic
#[must_use]
pub fn new(name: &str, obs_name: &str, orig_hash: u64) -> Self {
MapEqualityFeedback {
name: name.to_string(),
obs_name: obs_name.to_string(),
orig_hash,
phantom: PhantomData,
}
}
}
impl<M, S> Named for MapEqualityFeedback<M, S> { impl<M, S> Named for MapEqualityFeedback<M, S> {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
&self.name &self.name
} }
} }
impl<M, S> HasObserverName for MapEqualityFeedback<M, S> { impl<M, S> HasObserverName for MapEqualityFeedback<M, S> {
fn observer_name(&self) -> &str { fn observer_name(&self) -> &Cow<'static, str> {
&self.obs_name &self.obs_name
} }
} }
@ -407,7 +394,7 @@ where
/// A feedback factory for ensuring that the maps for minimized inputs are the same /// A feedback factory for ensuring that the maps for minimized inputs are the same
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct MapEqualityFactory<M, S> { pub struct MapEqualityFactory<M, S> {
obs_name: String, obs_name: Cow<'static, str>,
phantom: PhantomData<(M, S)>, phantom: PhantomData<(M, S)>,
} }
@ -418,14 +405,14 @@ where
/// Creates a new map equality feedback for the given observer /// Creates a new map equality feedback for the given observer
pub fn with_observer(obs: &M) -> Self { pub fn with_observer(obs: &M) -> Self {
Self { Self {
obs_name: obs.name().to_string(), obs_name: obs.name().clone(),
phantom: PhantomData, phantom: PhantomData,
} }
} }
} }
impl<M, S> HasObserverName for MapEqualityFactory<M, S> { impl<M, S> HasObserverName for MapEqualityFactory<M, S> {
fn observer_name(&self) -> &str { fn observer_name(&self) -> &Cow<'static, str> {
&self.obs_name &self.obs_name
} }
} }
@ -441,7 +428,7 @@ where
.match_name::<M>(self.observer_name()) .match_name::<M>(self.observer_name())
.expect("Should have been provided valid observer name."); .expect("Should have been provided valid observer name.");
MapEqualityFeedback { MapEqualityFeedback {
name: "MapEq".to_string(), name: Cow::from("MapEq"),
obs_name: self.obs_name.clone(), obs_name: self.obs_name.clone(),
orig_hash: obs.hash_simple(), orig_hash: obs.hash_simple(),
phantom: PhantomData, phantom: PhantomData,

View File

@ -1,5 +1,6 @@
//! The tracing stage can trace the target and enrich a testcase with metadata, for example for `CmpLog`. //! The tracing stage can trace the target and enrich a testcase with metadata, for example for `CmpLog`.
use alloc::borrow::Cow;
use core::{fmt::Debug, marker::PhantomData}; use core::{fmt::Debug, marker::PhantomData};
use libafl_bolts::Named; use libafl_bolts::Named;
@ -106,8 +107,9 @@ where
} }
impl<EM, TE, Z> Named for TracingStage<EM, TE, Z> { impl<EM, TE, Z> Named for TracingStage<EM, TE, Z> {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"TracingStage" static NAME: Cow<'static, str> = Cow::Borrowed("TracingStage");
&NAME
} }
} }
@ -159,8 +161,9 @@ impl<E, EM, SOT, Z> Named for ShadowTracingStage<E, EM, SOT, Z>
where where
E: UsesState, E: UsesState,
{ {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"ShadowTracingStage" static NAME: Cow<'static, str> = Cow::Borrowed("ShadowTracingStage");
&NAME
} }
} }

View File

@ -164,7 +164,7 @@ pub mod bolts_prelude {
#[cfg(all(unix, feature = "std"))] #[cfg(all(unix, feature = "std"))]
use alloc::boxed::Box; use alloc::boxed::Box;
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
use alloc::vec::Vec; use alloc::{borrow::Cow, vec::Vec};
#[cfg(all(not(feature = "xxh3"), feature = "alloc"))] #[cfg(all(not(feature = "xxh3"), feature = "alloc"))]
use core::hash::BuildHasher; use core::hash::BuildHasher;
#[cfg(any(feature = "xxh3", feature = "alloc"))] #[cfg(any(feature = "xxh3", feature = "alloc"))]
@ -231,9 +231,10 @@ use {
pub const IP_LOCALHOST: &str = "127.0.0.1"; pub const IP_LOCALHOST: &str = "127.0.0.1";
/// We need fixed names for many parts of this lib. /// We need fixed names for many parts of this lib.
#[cfg(feature = "alloc")]
pub trait Named { pub trait Named {
/// Provide the name of this element. /// Provide the name of this element.
fn name(&self) -> &str; fn name(&self) -> &Cow<'static, str>;
} }
#[cfg(feature = "errors_backtrace")] #[cfg(feature = "errors_backtrace")]
@ -681,11 +682,11 @@ pub trait AsSlice {
} }
/// Can be converted to a mutable slice /// Can be converted to a mutable slice
pub trait AsMutSlice { pub trait AsSliceMut {
/// Type of the entries in this mut slice /// Type of the entries in this mut slice
type Entry; type Entry;
/// Convert to a slice /// Convert to a slice
fn as_mut_slice(&mut self) -> &mut [Self::Entry]; fn as_slice_mut(&mut self) -> &mut [Self::Entry];
} }
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
@ -698,10 +699,10 @@ impl<T> AsSlice for Vec<T> {
} }
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
impl<T> AsMutSlice for Vec<T> { impl<T> AsSliceMut for Vec<T> {
type Entry = T; type Entry = T;
fn as_mut_slice(&mut self) -> &mut [Self::Entry] { fn as_slice_mut(&mut self) -> &mut [Self::Entry] {
self self
} }
} }
@ -722,18 +723,18 @@ impl<T> AsSlice for [T] {
} }
} }
impl<T> AsMutSlice for &mut [T] { impl<T> AsSliceMut for &mut [T] {
type Entry = T; type Entry = T;
fn as_mut_slice(&mut self) -> &mut [Self::Entry] { fn as_slice_mut(&mut self) -> &mut [Self::Entry] {
self self
} }
} }
impl<T> AsMutSlice for [T] { impl<T> AsSliceMut for [T] {
type Entry = T; type Entry = T;
fn as_mut_slice(&mut self) -> &mut [Self::Entry] { fn as_slice_mut(&mut self) -> &mut [Self::Entry] {
self self
} }
} }

View File

@ -394,7 +394,7 @@ impl Listener {
#[inline] #[inline]
#[allow(clippy::cast_ptr_alignment)] #[allow(clippy::cast_ptr_alignment)]
unsafe fn shmem2page_mut<SHM: ShMem>(afl_shmem: &mut SHM) -> *mut LlmpPage { unsafe fn shmem2page_mut<SHM: ShMem>(afl_shmem: &mut SHM) -> *mut LlmpPage {
afl_shmem.as_mut_slice().as_mut_ptr() as *mut LlmpPage afl_shmem.as_slice_mut().as_mut_ptr() as *mut LlmpPage
} }
/// Get sharedmem from a page /// Get sharedmem from a page

View File

@ -40,7 +40,7 @@ use uds::{UnixListenerExt, UnixSocketAddr, UnixStreamExt};
use crate::{ use crate::{
shmem::{ShMem, ShMemDescription, ShMemId, ShMemProvider}, shmem::{ShMem, ShMemDescription, ShMemId, ShMemProvider},
AsMutSlice, AsSlice, Error, AsSlice, AsSliceMut, Error,
}; };
/// The default server name for our abstract shmem server /// The default server name for our abstract shmem server
@ -102,13 +102,13 @@ where
self.inner.as_slice() self.inner.as_slice()
} }
} }
impl<SH> AsMutSlice for ServedShMem<SH> impl<SH> AsSliceMut for ServedShMem<SH>
where where
SH: ShMem, SH: ShMem,
{ {
type Entry = u8; type Entry = u8;
fn as_mut_slice(&mut self) -> &mut [u8] { fn as_slice_mut(&mut self) -> &mut [u8] {
self.inner.as_mut_slice() self.inner.as_slice_mut()
} }
} }

View File

@ -10,7 +10,7 @@ use core::{clone::Clone, fmt::Debug, slice};
use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde::{Deserialize, Deserializer, Serialize, Serializer};
use crate::{shmem::ShMem, AsMutSlice, AsSlice, IntoOwned, Truncate}; use crate::{shmem::ShMem, AsSlice, AsSliceMut, IntoOwned, Truncate};
/// Private part of the unsafe marker, making sure this cannot be initialized directly. /// Private part of the unsafe marker, making sure this cannot be initialized directly.
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
@ -562,7 +562,7 @@ impl<'a, 'it, T> IntoIterator for &'it mut OwnedMutSlice<'a, T> {
type IntoIter = IterMut<'it, T>; type IntoIter = IterMut<'it, T>;
fn into_iter(self) -> Self::IntoIter { fn into_iter(self) -> Self::IntoIter {
self.as_mut_slice().iter_mut() self.as_slice_mut().iter_mut()
} }
} }
@ -651,17 +651,17 @@ impl<'a, T: Sized> AsSlice for OwnedMutSlice<'a, T> {
} }
} }
} }
impl<'a, T: Sized> AsMutSlice for OwnedMutSlice<'a, T> { impl<'a, T: Sized> AsSliceMut for OwnedMutSlice<'a, T> {
type Entry = T; type Entry = T;
/// Get the value as mut slice /// Get the value as mut slice
#[must_use] #[must_use]
fn as_mut_slice(&mut self) -> &mut [T] { fn as_slice_mut(&mut self) -> &mut [T] {
match &mut self.inner { match &mut self.inner {
OwnedMutSliceInner::RefRaw(rr, len, _) => unsafe { OwnedMutSliceInner::RefRaw(rr, len, _) => unsafe {
slice::from_raw_parts_mut(*rr, *len) slice::from_raw_parts_mut(*rr, *len)
}, },
OwnedMutSliceInner::Ref(r) => r, OwnedMutSliceInner::Ref(r) => r,
OwnedMutSliceInner::Owned(v) => v.as_mut_slice(), OwnedMutSliceInner::Owned(v) => v.as_slice_mut(),
} }
} }
} }

View File

@ -31,7 +31,7 @@ pub use win32_shmem::{Win32ShMem, Win32ShMemProvider};
use crate::os::pipes::Pipe; use crate::os::pipes::Pipe;
#[cfg(all(feature = "std", unix, not(target_os = "haiku")))] #[cfg(all(feature = "std", unix, not(target_os = "haiku")))]
pub use crate::os::unix_shmem_server::{ServedShMemProvider, ShMemService}; pub use crate::os::unix_shmem_server::{ServedShMemProvider, ShMemService};
use crate::{AsMutSlice, AsSlice, Error}; use crate::{AsSlice, AsSliceMut, Error};
/// The standard sharedmem provider /// The standard sharedmem provider
#[cfg(all(windows, feature = "std"))] #[cfg(all(windows, feature = "std"))]
@ -192,7 +192,7 @@ impl Display for ShMemId {
/// A [`ShMem`] is an interface to shared maps. /// A [`ShMem`] is an interface to shared maps.
/// They are the backbone of [`crate::llmp`] for inter-process communication. /// They are the backbone of [`crate::llmp`] for inter-process communication.
/// All you need for scaling on a new target is to implement this interface, as well as the respective [`ShMemProvider`]. /// All you need for scaling on a new target is to implement this interface, as well as the respective [`ShMemProvider`].
pub trait ShMem: Sized + Debug + Clone + AsSlice<Entry = u8> + AsMutSlice<Entry = u8> { pub trait ShMem: Sized + Debug + Clone + AsSlice<Entry = u8> + AsSliceMut<Entry = u8> {
/// Get the id of this shared memory mapping /// Get the id of this shared memory mapping
fn id(&self) -> ShMemId; fn id(&self) -> ShMemId;
@ -218,7 +218,7 @@ pub trait ShMem: Sized + Debug + Clone + AsSlice<Entry = u8> + AsMutSlice<Entry
/// If the map is too small, returns `None` /// If the map is too small, returns `None`
fn as_mut_ptr_of<T: Sized>(&mut self) -> Option<*mut T> { fn as_mut_ptr_of<T: Sized>(&mut self) -> Option<*mut T> {
if self.len() >= mem::size_of::<T>() { if self.len() >= mem::size_of::<T>() {
Some(self.as_mut_slice().as_mut_ptr() as *mut T) Some(self.as_slice_mut().as_mut_ptr() as *mut T)
} else { } else {
None None
} }
@ -357,13 +357,13 @@ where
} }
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
impl<T> AsMutSlice for RcShMem<T> impl<T> AsSliceMut for RcShMem<T>
where where
T: ShMemProvider + Debug, T: ShMemProvider + Debug,
{ {
type Entry = u8; type Entry = u8;
fn as_mut_slice(&mut self) -> &mut [u8] { fn as_slice_mut(&mut self) -> &mut [u8] {
self.internal.as_mut_slice() self.internal.as_slice_mut()
} }
} }
@ -600,7 +600,7 @@ pub mod unix_shmem {
use crate::{ use crate::{
rands::{Rand, RandomSeed, StdRand}, rands::{Rand, RandomSeed, StdRand},
shmem::{ShMem, ShMemId, ShMemProvider}, shmem::{ShMem, ShMemId, ShMemProvider},
AsMutSlice, AsSlice, Error, AsSlice, AsSliceMut, Error,
}; };
// This is macOS's limit // This is macOS's limit
@ -782,9 +782,9 @@ pub mod unix_shmem {
} }
} }
impl AsMutSlice for MmapShMem { impl AsSliceMut for MmapShMem {
type Entry = u8; type Entry = u8;
fn as_mut_slice(&mut self) -> &mut [u8] { fn as_slice_mut(&mut self) -> &mut [u8] {
unsafe { slice::from_raw_parts_mut(self.map, self.map_size) } unsafe { slice::from_raw_parts_mut(self.map, self.map_size) }
} }
} }
@ -894,9 +894,9 @@ pub mod unix_shmem {
} }
} }
impl AsMutSlice for CommonUnixShMem { impl AsSliceMut for CommonUnixShMem {
type Entry = u8; type Entry = u8;
fn as_mut_slice(&mut self) -> &mut [u8] { fn as_slice_mut(&mut self) -> &mut [u8] {
unsafe { slice::from_raw_parts_mut(self.map, self.map_size) } unsafe { slice::from_raw_parts_mut(self.map, self.map_size) }
} }
} }
@ -964,7 +964,7 @@ pub mod unix_shmem {
use crate::{ use crate::{
shmem::{ShMem, ShMemId, ShMemProvider}, shmem::{ShMem, ShMemId, ShMemProvider},
AsMutSlice, AsSlice, Error, AsSlice, AsSliceMut, Error,
}; };
/// An ashmem based impl for linux/android /// An ashmem based impl for linux/android
@ -1104,10 +1104,10 @@ pub mod unix_shmem {
} }
} }
impl AsMutSlice for AshmemShMem { impl AsSliceMut for AshmemShMem {
type Entry = u8; type Entry = u8;
fn as_mut_slice(&mut self) -> &mut [u8] { fn as_slice_mut(&mut self) -> &mut [u8] {
unsafe { slice::from_raw_parts_mut(self.map, self.map_size) } unsafe { slice::from_raw_parts_mut(self.map, self.map_size) }
} }
} }
@ -1189,7 +1189,7 @@ pub mod win32_shmem {
use crate::{ use crate::{
shmem::{ShMem, ShMemId, ShMemProvider}, shmem::{ShMem, ShMemId, ShMemProvider},
AsMutSlice, AsSlice, Error, AsSlice, AsSliceMut, Error,
}; };
const INVALID_HANDLE_VALUE: isize = -1; const INVALID_HANDLE_VALUE: isize = -1;
@ -1303,9 +1303,9 @@ pub mod win32_shmem {
unsafe { slice::from_raw_parts(self.map, self.map_size) } unsafe { slice::from_raw_parts(self.map, self.map_size) }
} }
} }
impl AsMutSlice for Win32ShMem { impl AsSliceMut for Win32ShMem {
type Entry = u8; type Entry = u8;
fn as_mut_slice(&mut self) -> &mut [u8] { fn as_slice_mut(&mut self) -> &mut [u8] {
unsafe { slice::from_raw_parts_mut(self.map, self.map_size) } unsafe { slice::from_raw_parts_mut(self.map, self.map_size) }
} }
} }
@ -1395,7 +1395,7 @@ impl<T: ShMem> ShMemCursor<T> {
/// Slice from the current location on this map to the end, mutable /// Slice from the current location on this map to the end, mutable
fn empty_slice_mut(&mut self) -> &mut [u8] { fn empty_slice_mut(&mut self) -> &mut [u8] {
&mut (self.inner.as_mut_slice()[self.pos..]) &mut (self.inner.as_slice_mut()[self.pos..])
} }
} }
@ -1470,7 +1470,7 @@ mod tests {
use crate::{ use crate::{
shmem::{ShMemProvider, StdShMemProvider}, shmem::{ShMemProvider, StdShMemProvider},
AsMutSlice, AsSlice, AsSlice, AsSliceMut,
}; };
#[test] #[test]
@ -1479,7 +1479,7 @@ mod tests {
fn test_shmem_service() { fn test_shmem_service() {
let mut provider = StdShMemProvider::new().unwrap(); let mut provider = StdShMemProvider::new().unwrap();
let mut map = provider.new_shmem(1024).unwrap(); let mut map = provider.new_shmem(1024).unwrap();
map.as_mut_slice()[0] = 1; map.as_slice_mut()[0] = 1;
assert!(map.as_slice()[0] == 1); assert!(map.as_slice()[0] == 1);
} }
} }

View File

@ -1,11 +1,12 @@
//! Compiletime lists/tuples used throughout the `LibAFL` universe //! Compiletime lists/tuples used throughout the `LibAFL` universe
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
use alloc::vec::Vec; use alloc::{borrow::Cow, vec::Vec};
#[rustversion::not(nightly)] #[rustversion::not(nightly)]
use core::any::type_name; use core::any::type_name;
use core::{ use core::{
any::TypeId, any::TypeId,
marker::PhantomData,
mem::transmute, mem::transmute,
ptr::{addr_of, addr_of_mut}, ptr::{addr_of, addr_of_mut},
}; };
@ -14,7 +15,9 @@ pub use tuple_list::{tuple_list, tuple_list_type, TupleList};
#[cfg(any(feature = "xxh3", feature = "alloc"))] #[cfg(any(feature = "xxh3", feature = "alloc"))]
use crate::hash_std; use crate::hash_std;
use crate::{HasLen, Named}; use crate::HasLen;
#[cfg(feature = "alloc")]
use crate::Named;
/// Returns if the type `T` is equal to `U` /// Returns if the type `T` is equal to `U`
/// From <https://stackoverflow.com/a/60138532/7658998> /// From <https://stackoverflow.com/a/60138532/7658998>
@ -407,31 +410,36 @@ where
} }
} }
#[cfg(feature = "alloc")]
/// A named tuple /// A named tuple
pub trait NamedTuple: HasConstLen { pub trait NamedTuple: HasConstLen {
/// Gets the name of this tuple /// Gets the name of this tuple
fn name(&self, index: usize) -> Option<&str>; fn name(&self, index: usize) -> Option<&Cow<'static, str>>;
} }
#[cfg(feature = "alloc")]
impl NamedTuple for () { impl NamedTuple for () {
fn name(&self, _index: usize) -> Option<&str> { fn name(&self, _index: usize) -> Option<&Cow<'static, str>> {
None None
} }
} }
#[cfg(feature = "alloc")]
impl Named for () { impl Named for () {
#[inline] #[inline]
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"Empty" static NAME: Cow<'static, str> = Cow::Borrowed("Empty");
&NAME
} }
} }
#[cfg(feature = "alloc")]
impl<Head, Tail> NamedTuple for (Head, Tail) impl<Head, Tail> NamedTuple for (Head, Tail)
where where
Head: Named, Head: Named,
Tail: NamedTuple, Tail: NamedTuple,
{ {
fn name(&self, index: usize) -> Option<&str> { fn name(&self, index: usize) -> Option<&Cow<'static, str>> {
if index == 0 { if index == 0 {
Some(self.0.name()) Some(self.0.name())
} else { } else {
@ -445,6 +453,7 @@ where
/// # Note /// # Note
/// This operation may not be 100% accurate with Rust stable, see the notes for [`type_eq`] /// This operation may not be 100% accurate with Rust stable, see the notes for [`type_eq`]
/// (in `nightly`, it uses [specialization](https://stackoverflow.com/a/60138532/7658998)). /// (in `nightly`, it uses [specialization](https://stackoverflow.com/a/60138532/7658998)).
#[cfg(feature = "alloc")]
pub trait MatchName { pub trait MatchName {
/// Match for a name and return the borrowed value /// Match for a name and return the borrowed value
fn match_name<T>(&self, name: &str) -> Option<&T>; fn match_name<T>(&self, name: &str) -> Option<&T>;
@ -452,6 +461,7 @@ pub trait MatchName {
fn match_name_mut<T>(&mut self, name: &str) -> Option<&mut T>; fn match_name_mut<T>(&mut self, name: &str) -> Option<&mut T>;
} }
#[cfg(feature = "alloc")]
impl MatchName for () { impl MatchName for () {
fn match_name<T>(&self, _name: &str) -> Option<&T> { fn match_name<T>(&self, _name: &str) -> Option<&T> {
None None
@ -461,6 +471,7 @@ impl MatchName for () {
} }
} }
#[cfg(feature = "alloc")]
impl<Head, Tail> MatchName for (Head, Tail) impl<Head, Tail> MatchName for (Head, Tail)
where where
Head: Named, Head: Named,
@ -484,6 +495,7 @@ where
} }
/// Finds an element of a `type` by the given `name`. /// Finds an element of a `type` by the given `name`.
#[cfg(feature = "alloc")]
pub trait MatchNameAndType { pub trait MatchNameAndType {
/// Finds an element of a `type` by the given `name`, and returns a borrow, or [`Option::None`]. /// Finds an element of a `type` by the given `name`, and returns a borrow, or [`Option::None`].
fn match_name_type<T: 'static>(&self, name: &str) -> Option<&T>; fn match_name_type<T: 'static>(&self, name: &str) -> Option<&T>;
@ -491,6 +503,7 @@ pub trait MatchNameAndType {
fn match_name_type_mut<T: 'static>(&mut self, name: &str) -> Option<&mut T>; fn match_name_type_mut<T: 'static>(&mut self, name: &str) -> Option<&mut T>;
} }
#[cfg(feature = "alloc")]
impl MatchNameAndType for () { impl MatchNameAndType for () {
fn match_name_type<T: 'static>(&self, _name: &str) -> Option<&T> { fn match_name_type<T: 'static>(&self, _name: &str) -> Option<&T> {
None None
@ -500,6 +513,7 @@ impl MatchNameAndType for () {
} }
} }
#[cfg(feature = "alloc")]
impl<Head, Tail> MatchNameAndType for (Head, Tail) impl<Head, Tail> MatchNameAndType for (Head, Tail)
where where
Head: 'static + Named, Head: 'static + Named,
@ -524,6 +538,54 @@ where
} }
} }
/// Structs that has `ReReference `
/// You should use this when you want to avoid specifying types using `match_name_type_mut`
#[cfg(feature = "alloc")]
pub trait Referenceable: Named {
/// Return the `ReReference `
fn type_ref(&self) -> ReReference<Self> {
ReReference {
name: Named::name(self).clone(),
phantom: PhantomData,
}
}
}
#[cfg(feature = "alloc")]
impl<N> Referenceable for N where N: Named {}
/// Empty object with the type T
#[derive(Debug)]
#[cfg(feature = "alloc")]
pub struct ReReference<T: ?Sized> {
name: Cow<'static, str>,
phantom: PhantomData<T>,
}
/// Search using `ReReference `
#[cfg(feature = "alloc")]
pub trait MatchNameRef {
/// Search using name and `ReReference `
fn match_by_ref<T>(&self, rf: ReReference<T>) -> Option<&T>;
/// Search using name and `ReReference `
fn match_by_ref_mut<T>(&mut self, rf: ReReference<T>) -> Option<&mut T>;
}
#[cfg(feature = "alloc")]
impl<M> MatchNameRef for M
where
M: MatchName,
{
fn match_by_ref<T>(&self, rf: ReReference<T>) -> Option<&T> {
self.match_name::<T>(&rf.name)
}
fn match_by_ref_mut<T>(&mut self, rf: ReReference<T>) -> Option<&mut T> {
self.match_name_mut::<T>(&rf.name)
}
}
/// Allows prepending of values to a tuple /// Allows prepending of values to a tuple
pub trait Prepend<T> { pub trait Prepend<T> {
/// The Resulting [`TupleList`], of an [`Prepend::prepend()`] call, /// The Resulting [`TupleList`], of an [`Prepend::prepend()`] call,

View File

@ -196,7 +196,7 @@ where
// The index is modulo by the length, therefore it is always in bounds // The index is modulo by the length, therefore it is always in bounds
let len = self.hitcounts_map.len(); let len = self.hitcounts_map.len();
self.hitcounts_map self.hitcounts_map
.as_mut_slice() .as_slice_mut()
.get_unchecked_mut(hash % len) .get_unchecked_mut(hash % len)
}; };
*val = val.saturating_add(1); *val = val.saturating_add(1);

View File

@ -1,5 +1,6 @@
//! Errors that can be caught by the `libafl_frida` address sanitizer. //! Errors that can be caught by the `libafl_frida` address sanitizer.
use std::{ use std::{
borrow::Cow,
fmt::Debug, fmt::Debug,
io::Write, io::Write,
marker::PhantomData, marker::PhantomData,
@ -38,6 +39,8 @@ use crate::{
alloc::AllocationMetadata, asan::asan_rt::ASAN_SAVE_REGISTER_COUNT, utils::disas_count, alloc::AllocationMetadata, asan::asan_rt::ASAN_SAVE_REGISTER_COUNT, utils::disas_count,
}; };
static ASAN_ERRORS_NAME: Cow<'static, str> = Cow::Borrowed("AsanErrors");
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub(crate) struct AsanReadWriteError { pub(crate) struct AsanReadWriteError {
pub registers: [usize; ASAN_SAVE_REGISTER_COUNT], pub registers: [usize; ASAN_SAVE_REGISTER_COUNT],
@ -587,8 +590,8 @@ where
impl Named for AsanErrorsObserver { impl Named for AsanErrorsObserver {
#[inline] #[inline]
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"AsanErrors" &ASAN_ERRORS_NAME
} }
} }
@ -662,7 +665,7 @@ where
OT: ObserversTuple<S>, OT: ObserversTuple<S>,
{ {
let observer = observers let observer = observers
.match_name::<AsanErrorsObserver>("AsanErrors") .match_name::<AsanErrorsObserver>(&ASAN_ERRORS_NAME)
.expect("An AsanErrorsFeedback needs an AsanErrorsObserver"); .expect("An AsanErrorsFeedback needs an AsanErrorsObserver");
let errors = observer.errors(); let errors = observer.errors();
if errors.is_empty() { if errors.is_empty() {
@ -698,8 +701,8 @@ where
impl<S> Named for AsanErrorsFeedback<S> { impl<S> Named for AsanErrorsFeedback<S> {
#[inline] #[inline]
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"AsanErrors" &ASAN_ERRORS_NAME
} }
} }

View File

@ -1,5 +1,6 @@
use alloc::rc::Rc; use alloc::rc::Rc;
use core::{cell::RefCell, fmt::Debug}; use core::{cell::RefCell, fmt::Debug};
use std::borrow::Cow;
use libafl::{ use libafl::{
alloc, alloc,
@ -36,8 +37,9 @@ impl LibfuzzerKeepFeedback {
} }
impl Named for LibfuzzerKeepFeedback { impl Named for LibfuzzerKeepFeedback {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"libfuzzer-keep" static NAME: Cow<'static, str> = Cow::Borrowed("libfuzzer-keep");
&NAME
} }
} }
@ -90,8 +92,9 @@ impl LibfuzzerCrashCauseFeedback {
} }
impl Named for LibfuzzerCrashCauseFeedback { impl Named for LibfuzzerCrashCauseFeedback {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"crash-cause" static NAME: Cow<'static, str> = Cow::Borrowed("crash-cause");
&NAME
} }
} }

View File

@ -1,4 +1,5 @@
use std::{ use std::{
borrow::Cow,
fmt::Debug, fmt::Debug,
hash::{Hash, Hasher}, hash::{Hash, Hasher},
}; };
@ -37,7 +38,7 @@ pub trait ValueObserver: for<'de> Deserialize<'de> + Serialize + Debug + Named {
#[derive(Deserialize, Serialize, Debug)] #[derive(Deserialize, Serialize, Debug)]
pub struct MappedEdgeMapObserver<M, O> { pub struct MappedEdgeMapObserver<M, O> {
inner: M, inner: M,
name: String, name: Cow<'static, str>,
value_observer: O, value_observer: O,
} }
@ -48,7 +49,7 @@ where
{ {
pub fn new(obs: M, value_obs: O) -> Self { pub fn new(obs: M, value_obs: O) -> Self {
Self { Self {
name: format!("{}_{}", value_obs.name(), obs.name()), name: Cow::from(format!("{}_{}", value_obs.name(), obs.name())),
inner: obs, inner: obs,
value_observer: value_obs, value_observer: value_obs,
} }
@ -77,7 +78,7 @@ where
} }
impl<M, O> Named for MappedEdgeMapObserver<M, O> { impl<M, O> Named for MappedEdgeMapObserver<M, O> {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
&self.name &self.name
} }
} }
@ -251,8 +252,9 @@ impl ValueObserver for SizeValueObserver {
} }
impl Named for SizeValueObserver { impl Named for SizeValueObserver {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"size" static NAME: Cow<'static, str> = Cow::Borrowed("size");
&NAME
} }
} }
@ -295,7 +297,7 @@ impl ValueObserver for TimeValueObserver {
} }
impl Named for TimeValueObserver { impl Named for TimeValueObserver {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
self.time_obs.name() self.time_obs.name()
} }
} }
@ -356,8 +358,9 @@ impl ValueObserver for SizeTimeValueObserver {
} }
impl Named for SizeTimeValueObserver { impl Named for SizeTimeValueObserver {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"size_time" static NAME: Cow<'static, str> = Cow::Borrowed("size_time");
&NAME
} }
} }

View File

@ -101,7 +101,7 @@ impl<T> __IncompleteArrayField<T> {
::std::slice::from_raw_parts(self.as_ptr(), len) ::std::slice::from_raw_parts(self.as_ptr(), len)
} }
#[inline] #[inline]
pub unsafe fn as_mut_slice(&mut self, len: usize) -> &mut [T] { pub unsafe fn as_slice_mut(&mut self, len: usize) -> &mut [T] {
::std::slice::from_raw_parts_mut(self.as_mut_ptr(), len) ::std::slice::from_raw_parts_mut(self.as_mut_ptr(), len)
} }
} }

View File

@ -27,7 +27,7 @@ use libafl_bolts::{
rands::StdRand, rands::StdRand,
shmem::{ShMem, ShMemProvider, UnixShMemProvider}, shmem::{ShMem, ShMemProvider, UnixShMemProvider},
tuples::{tuple_list, Merge}, tuples::{tuple_list, Merge},
AsMutSlice, AsSliceMut,
}; };
use typed_builder::TypedBuilder; use typed_builder::TypedBuilder;
@ -120,7 +120,7 @@ impl<'a> ForkserverBytesCoverageSugar<'a> {
// Coverage map shared between target and fuzzer // Coverage map shared between target and fuzzer
let mut shmem = shmem_provider_client.new_shmem(MAP_SIZE).unwrap(); let mut shmem = shmem_provider_client.new_shmem(MAP_SIZE).unwrap();
shmem.write_to_env("__AFL_SHM_ID").unwrap(); shmem.write_to_env("__AFL_SHM_ID").unwrap();
let shmem_map = shmem.as_mut_slice(); let shmem_map = shmem.as_slice_mut();
// To let know the AFL++ binary that we have a big map // To let know the AFL++ binary that we have a big map
std::env::set_var("AFL_MAP_SIZE", format!("{MAP_SIZE}")); std::env::set_var("AFL_MAP_SIZE", format!("{MAP_SIZE}"));

View File

@ -1,7 +1,4 @@
use alloc::{ use alloc::{borrow::Cow, vec::Vec};
string::{String, ToString},
vec::Vec,
};
use core::{fmt::Debug, marker::PhantomData}; use core::{fmt::Debug, marker::PhantomData};
use libafl::{ use libafl::{
@ -74,7 +71,7 @@ where
{ {
cmp_map: OwnedRefMut<'a, AFLppCmpLogMap>, cmp_map: OwnedRefMut<'a, AFLppCmpLogMap>,
size: Option<OwnedRefMut<'a, usize>>, size: Option<OwnedRefMut<'a, usize>>,
name: String, name: Cow<'static, str>,
add_meta: bool, add_meta: bool,
original: <AFLppCmpValuesMetadata as CmpObserverMetadata<'a, AFLppCmpLogMap>>::Data, original: <AFLppCmpValuesMetadata as CmpObserverMetadata<'a, AFLppCmpLogMap>>::Data,
phantom: PhantomData<S>, phantom: PhantomData<S>,
@ -183,7 +180,7 @@ impl<'a, S> Named for AFLppCmpLogObserver<'a, S>
where where
S: UsesInput + HasMetadata, S: UsesInput + HasMetadata,
{ {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
&self.name &self.name
} }
} }
@ -200,7 +197,7 @@ where
add_meta: bool, add_meta: bool,
) -> Self { ) -> Self {
Self { Self {
name: name.to_string(), name: Cow::from(name),
size: None, size: None,
cmp_map, cmp_map,
add_meta, add_meta,
@ -223,7 +220,7 @@ where
size: OwnedRefMut<'a, usize>, size: OwnedRefMut<'a, usize>,
) -> Self { ) -> Self {
Self { Self {
name: name.to_string(), name: Cow::from(name),
size: Some(size), size: Some(size),
cmp_map, cmp_map,
add_meta, add_meta,

View File

@ -2,7 +2,7 @@
//! The values will then be used in subsequent mutations. //! The values will then be used in subsequent mutations.
//! //!
use alloc::string::{String, ToString}; use alloc::borrow::Cow;
use core::fmt::Debug; use core::fmt::Debug;
use libafl::{ use libafl::{
@ -22,7 +22,7 @@ pub struct CmpLogObserver {
map: OwnedMutPtr<CmpLogMap>, map: OwnedMutPtr<CmpLogMap>,
size: Option<OwnedMutPtr<usize>>, size: Option<OwnedMutPtr<usize>>,
add_meta: bool, add_meta: bool,
name: String, name: Cow<'static, str>,
} }
impl<'a, S> CmpObserver<'a, CmpLogMap, S, CmpValuesMetadata> for CmpLogObserver impl<'a, S> CmpObserver<'a, CmpLogMap, S, CmpValuesMetadata> for CmpLogObserver
@ -78,7 +78,7 @@ where
} }
impl Named for CmpLogObserver { impl Named for CmpLogObserver {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
&self.name &self.name
} }
} }
@ -91,7 +91,7 @@ impl CmpLogObserver {
#[must_use] #[must_use]
pub unsafe fn with_map_ptr(name: &'static str, map: *mut CmpLogMap, add_meta: bool) -> Self { pub unsafe fn with_map_ptr(name: &'static str, map: *mut CmpLogMap, add_meta: bool) -> Self {
Self { Self {
name: name.to_string(), name: Cow::from(name),
size: None, size: None,
add_meta, add_meta,
map: OwnedMutPtr::Ptr(map), map: OwnedMutPtr::Ptr(map),

View File

@ -1,4 +1,7 @@
use alloc::string::{String, ToString}; use alloc::{
borrow::Cow,
string::{String, ToString},
};
use core::marker::PhantomData; use core::marker::PhantomData;
#[cfg(feature = "introspection")] #[cfg(feature = "introspection")]
@ -32,8 +35,9 @@ where
} }
impl<EM, TE, Z> Named for AFLppCmplogTracingStage<EM, TE, Z> { impl<EM, TE, Z> Named for AFLppCmplogTracingStage<EM, TE, Z> {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"AFLppCmplogTracingStage" static NAME: Cow<'static, str> = Cow::Borrowed("AFLppCmplogTracingStage");
&NAME
} }
} }

View File

@ -1,6 +1,6 @@
//! Coverage maps as static mut array //! Coverage maps as static mut array
use alloc::string::String; use alloc::borrow::Cow;
#[cfg(any(target_os = "linux", target_vendor = "apple"))] #[cfg(any(target_os = "linux", target_vendor = "apple"))]
use libafl::{mutators::Tokens, Error}; use libafl::{mutators::Tokens, Error};
@ -108,7 +108,7 @@ pub unsafe fn edges_map_mut_slice<'a>() -> OwnedMutSlice<'a, u8> {
/// This will dereference [`edges_map_mut_ptr`] and crash if it is not a valid address. /// This will dereference [`edges_map_mut_ptr`] and crash if it is not a valid address.
pub unsafe fn std_edges_map_observer<'a, S>(name: S) -> StdMapObserver<'a, u8, false> pub unsafe fn std_edges_map_observer<'a, S>(name: S) -> StdMapObserver<'a, u8, false>
where where
S: Into<String>, S: Into<Cow<'static, str>>,
{ {
StdMapObserver::from_mut_slice(name, edges_map_mut_slice()) StdMapObserver::from_mut_slice(name, edges_map_mut_slice())
} }
@ -152,7 +152,7 @@ pub use swap::*;
#[cfg(feature = "pointer_maps")] #[cfg(feature = "pointer_maps")]
mod swap { mod swap {
use alloc::string::{String, ToString}; use alloc::borrow::Cow;
use core::fmt::Debug; use core::fmt::Debug;
use libafl::{ use libafl::{
@ -160,7 +160,7 @@ mod swap {
observers::{DifferentialObserver, Observer, ObserversTuple, StdMapObserver}, observers::{DifferentialObserver, Observer, ObserversTuple, StdMapObserver},
Error, Error,
}; };
use libafl_bolts::{ownedref::OwnedMutSlice, AsMutSlice, Named}; use libafl_bolts::{ownedref::OwnedMutSlice, AsSliceMut, Named};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use super::{EDGES_MAP_PTR, EDGES_MAP_PTR_NUM}; use super::{EDGES_MAP_PTR, EDGES_MAP_PTR_NUM};
@ -173,9 +173,9 @@ mod swap {
pub struct DifferentialAFLMapSwapObserver<'a, 'b> { pub struct DifferentialAFLMapSwapObserver<'a, 'b> {
first_map: OwnedMutSlice<'a, u8>, first_map: OwnedMutSlice<'a, u8>,
second_map: OwnedMutSlice<'b, u8>, second_map: OwnedMutSlice<'b, u8>,
first_name: String, first_name: Cow<'static, str>,
second_name: String, second_name: Cow<'static, str>,
name: String, name: Cow<'static, str>,
} }
impl<'a, 'b> DifferentialAFLMapSwapObserver<'a, 'b> { impl<'a, 'b> DifferentialAFLMapSwapObserver<'a, 'b> {
@ -185,15 +185,15 @@ mod swap {
second: &mut StdMapObserver<'b, u8, D2>, second: &mut StdMapObserver<'b, u8, D2>,
) -> Self { ) -> Self {
Self { Self {
first_name: first.name().to_string(), first_name: first.name().clone(),
second_name: second.name().to_string(), second_name: second.name().clone(),
name: format!("differential_{}_{}", first.name(), second.name()), name: Cow::from(format!("differential_{}_{}", first.name(), second.name())),
first_map: unsafe { first_map: unsafe {
let slice = first.map_mut().as_mut_slice(); let slice = first.map_mut().as_slice_mut();
OwnedMutSlice::from_raw_parts_mut(slice.as_mut_ptr(), slice.len()) OwnedMutSlice::from_raw_parts_mut(slice.as_mut_ptr(), slice.len())
}, },
second_map: unsafe { second_map: unsafe {
let slice = second.map_mut().as_mut_slice(); let slice = second.map_mut().as_slice_mut();
OwnedMutSlice::from_raw_parts_mut(slice.as_mut_ptr(), slice.len()) OwnedMutSlice::from_raw_parts_mut(slice.as_mut_ptr(), slice.len())
}, },
} }
@ -225,7 +225,7 @@ mod swap {
} }
impl<'a, 'b> Named for DifferentialAFLMapSwapObserver<'a, 'b> { impl<'a, 'b> Named for DifferentialAFLMapSwapObserver<'a, 'b> {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
&self.name &self.name
} }
} }
@ -240,7 +240,7 @@ mod swap {
S: UsesInput, S: UsesInput,
{ {
fn pre_observe_first(&mut self, _: &mut OTA) -> Result<(), Error> { fn pre_observe_first(&mut self, _: &mut OTA) -> Result<(), Error> {
let slice = self.first_map.as_mut_slice(); let slice = self.first_map.as_slice_mut();
unsafe { unsafe {
EDGES_MAP_PTR = slice.as_mut_ptr(); EDGES_MAP_PTR = slice.as_mut_ptr();
EDGES_MAP_PTR_NUM = slice.len(); EDGES_MAP_PTR_NUM = slice.len();
@ -249,7 +249,7 @@ mod swap {
} }
fn pre_observe_second(&mut self, _: &mut OTB) -> Result<(), Error> { fn pre_observe_second(&mut self, _: &mut OTB) -> Result<(), Error> {
let slice = self.second_map.as_mut_slice(); let slice = self.second_map.as_slice_mut();
unsafe { unsafe {
EDGES_MAP_PTR = slice.as_mut_ptr(); EDGES_MAP_PTR = slice.as_mut_ptr();
EDGES_MAP_PTR_NUM = slice.len(); EDGES_MAP_PTR_NUM = slice.len();

View File

@ -1,4 +1,7 @@
use alloc::rc::{Rc, Weak}; use alloc::{
borrow::Cow,
rc::{Rc, Weak},
};
use std::{ use std::{
cell::RefCell, cell::RefCell,
marker::PhantomData, marker::PhantomData,
@ -279,8 +282,9 @@ where
} }
impl<MT, SM> Named for LLVMCustomMutator<MT, SM, false> { impl<MT, SM> Named for LLVMCustomMutator<MT, SM, false> {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"LLVMCustomMutator" static NAME: Cow<'static, str> = Cow::Borrowed("LLVMCustomMutator");
&NAME
} }
} }
@ -353,8 +357,9 @@ where
} }
impl<MT, SM> Named for LLVMCustomMutator<MT, SM, true> { impl<MT, SM> Named for LLVMCustomMutator<MT, SM, true> {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"LLVMCustomCrossover" static NAME: Cow<'static, str> = Cow::Borrowed("LLVMCustomCrossover");
&NAME
} }
} }

View File

@ -1,3 +1,4 @@
use alloc::borrow::Cow;
use core::{ffi::c_void, fmt::Debug}; use core::{ffi::c_void, fmt::Debug};
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
@ -68,7 +69,7 @@ pub unsafe extern "C" fn __sanitizer_free_hook(ptr: *const c_void) {
} }
} }
const OOM_OBS_NAME: &str = "libfuzzer-like-oom"; static OOM_OBS_NAME: Cow<'static, str> = Cow::Borrowed("libfuzzer-like-oom");
/// Observer which detects if the target would run out of memory or otherwise violate the permissible usage of malloc /// Observer which detects if the target would run out of memory or otherwise violate the permissible usage of malloc
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
@ -88,8 +89,8 @@ impl OomObserver {
impl Named for OomObserver { impl Named for OomObserver {
// strictly one name to prevent two from being registered // strictly one name to prevent two from being registered
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
OOM_OBS_NAME &OOM_OBS_NAME
} }
} }
@ -142,8 +143,9 @@ impl OomFeedback {
} }
impl Named for OomFeedback { impl Named for OomFeedback {
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
"oom" static NAME: Cow<'static, str> = Cow::Borrowed("oom");
&NAME
} }
} }

View File

@ -2,7 +2,7 @@
use alloc::vec::Vec; use alloc::vec::Vec;
use core::ptr::addr_of_mut; use core::ptr::addr_of_mut;
use libafl_bolts::{ownedref::OwnedMutSlice, AsMutSlice, AsSlice}; use libafl_bolts::{ownedref::OwnedMutSlice, AsSlice, AsSliceMut};
/// A [`Vec`] of `8-bit-counters` maps for multiple modules. /// A [`Vec`] of `8-bit-counters` maps for multiple modules.
/// They are initialized by calling [`__sanitizer_cov_8bit_counters_init`]( /// They are initialized by calling [`__sanitizer_cov_8bit_counters_init`](
@ -32,9 +32,9 @@ pub unsafe fn extra_counters() -> Vec<OwnedMutSlice<'static, u8>> {
pub extern "C" fn __sanitizer_cov_8bit_counters_init(start: *mut u8, stop: *mut u8) { pub extern "C" fn __sanitizer_cov_8bit_counters_init(start: *mut u8, stop: *mut u8) {
unsafe { unsafe {
for existing in &mut *addr_of_mut!(COUNTERS_MAPS) { for existing in &mut *addr_of_mut!(COUNTERS_MAPS) {
let range = existing.as_mut_slice().as_mut_ptr() let range = existing.as_slice_mut().as_mut_ptr()
..=existing ..=existing
.as_mut_slice() .as_slice_mut()
.as_mut_ptr() .as_mut_ptr()
.add(existing.as_slice().len()); .add(existing.as_slice().len());
if range.contains(&start) || range.contains(&stop) { if range.contains(&start) || range.contains(&stop) {
@ -59,10 +59,7 @@ pub use self::observers::{counters_maps_observer, CountersMultiMapObserver};
#[cfg(feature = "observers")] #[cfg(feature = "observers")]
mod observers { mod observers {
use alloc::{ use alloc::{borrow::Cow, vec::Vec};
string::{String, ToString},
vec::Vec,
};
use core::{ use core::{
fmt::Debug, fmt::Debug,
hash::{Hash, Hasher}, hash::{Hash, Hasher},
@ -78,7 +75,7 @@ mod observers {
Error, Error,
}; };
use libafl_bolts::{ use libafl_bolts::{
ownedref::OwnedMutSlice, AsIter, AsIterMut, AsMutSlice, AsSlice, HasLen, Named, ownedref::OwnedMutSlice, AsIter, AsIterMut, AsSlice, AsSliceMut, HasLen, Named,
}; };
use meminterval::IntervalTree; use meminterval::IntervalTree;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -122,7 +119,7 @@ mod observers {
intervals: IntervalTree<usize, usize>, intervals: IntervalTree<usize, usize>,
len: usize, len: usize,
initial: u8, initial: u8,
name: String, name: Cow<'static, str>,
iter_idx: usize, iter_idx: usize,
} }
@ -147,8 +144,8 @@ mod observers {
impl<const DIFFERENTIAL: bool> Named for CountersMultiMapObserver<DIFFERENTIAL> { impl<const DIFFERENTIAL: bool> Named for CountersMultiMapObserver<DIFFERENTIAL> {
#[inline] #[inline]
fn name(&self) -> &str { fn name(&self) -> &Cow<'static, str> {
self.name.as_str() &self.name
} }
} }
@ -200,7 +197,7 @@ mod observers {
let elem = self.intervals.query_mut(idx..=idx).next().unwrap(); let elem = self.intervals.query_mut(idx..=idx).next().unwrap();
let i = elem.value; let i = elem.value;
let j = idx - elem.interval.start; let j = idx - elem.interval.start;
unsafe { &mut (*addr_of_mut!(COUNTERS_MAPS[*i])).as_mut_slice()[j] } unsafe { &mut (*addr_of_mut!(COUNTERS_MAPS[*i])).as_slice_mut()[j] }
} }
#[inline] #[inline]
@ -229,7 +226,7 @@ mod observers {
fn reset_map(&mut self) -> Result<(), Error> { fn reset_map(&mut self) -> Result<(), Error> {
let initial = self.initial(); let initial = self.initial();
for map in unsafe { &mut *addr_of_mut!(COUNTERS_MAPS) } { for map in unsafe { &mut *addr_of_mut!(COUNTERS_MAPS) } {
for x in map.as_mut_slice() { for x in map.as_slice_mut() {
*x = initial; *x = initial;
} }
} }
@ -277,7 +274,7 @@ mod observers {
Self { Self {
intervals, intervals,
len: idx, len: idx,
name: name.to_string(), name: Cow::from(name),
initial: u8::default(), initial: u8::default(),
iter_idx: 0, iter_idx: 0,
} }
@ -308,7 +305,7 @@ mod observers {
unsafe { &mut *addr_of_mut!(COUNTERS_MAPS) } unsafe { &mut *addr_of_mut!(COUNTERS_MAPS) }
.iter_mut() .iter_mut()
.for_each(|m| { .for_each(|m| {
let l = m.as_mut_slice().len(); let l = m.as_slice_mut().len();
intervals.insert(idx..(idx + l), v); intervals.insert(idx..(idx + l), v);
idx += l; idx += l;
v += 1; v += 1;
@ -316,7 +313,7 @@ mod observers {
Self { Self {
intervals, intervals,
len: idx, len: idx,
name: name.to_string(), name: Cow::from(name),
initial: u8::default(), initial: u8::default(),
iter_idx: 0, iter_idx: 0,
} }

View File

@ -11,7 +11,7 @@ use libafl::{
use libafl_bolts::{ use libafl_bolts::{
fs::{InputFile, INPUTFILE_STD}, fs::{InputFile, INPUTFILE_STD},
shmem::{ShMem, ShMemProvider, StdShMemProvider}, shmem::{ShMem, ShMemProvider, StdShMemProvider},
AsMutSlice, AsSlice, AsSlice, AsSliceMut,
}; };
use tinyinst::tinyinst::{litecov::RunResult, TinyInst}; use tinyinst::tinyinst::{litecov::RunResult, TinyInst};
@ -65,9 +65,9 @@ where
let size = target_bytes.as_slice().len(); let size = target_bytes.as_slice().len();
let size_in_bytes = size.to_ne_bytes(); let size_in_bytes = size.to_ne_bytes();
// The first four bytes tells the size of the shmem. // The first four bytes tells the size of the shmem.
shmem.as_mut_slice()[..SHMEM_FUZZ_HDR_SIZE] shmem.as_slice_mut()[..SHMEM_FUZZ_HDR_SIZE]
.copy_from_slice(&size_in_bytes[..SHMEM_FUZZ_HDR_SIZE]); .copy_from_slice(&size_in_bytes[..SHMEM_FUZZ_HDR_SIZE]);
shmem.as_mut_slice()[SHMEM_FUZZ_HDR_SIZE..(SHMEM_FUZZ_HDR_SIZE + size)] shmem.as_slice_mut()[SHMEM_FUZZ_HDR_SIZE..(SHMEM_FUZZ_HDR_SIZE + size)]
.copy_from_slice(target_bytes.as_slice()); .copy_from_slice(target_bytes.as_slice());
} }
None => { None => {
@ -240,7 +240,7 @@ where
// shmem.write_to_env("__TINY_SHM_FUZZ_ID")?; // shmem.write_to_env("__TINY_SHM_FUZZ_ID")?;
let size_in_bytes = (MAX_FILE + SHMEM_FUZZ_HDR_SIZE).to_ne_bytes(); let size_in_bytes = (MAX_FILE + SHMEM_FUZZ_HDR_SIZE).to_ne_bytes();
shmem.as_mut_slice()[..4].clone_from_slice(&size_in_bytes[..4]); shmem.as_slice_mut()[..4].clone_from_slice(&size_in_bytes[..4]);
(Some(shmem), Some(shmem_id)) (Some(shmem), Some(shmem_id))
} }