Add AsSlice, AsMutSlice traits, refactor MapObservers to be iterable, and have associated types (#477)
* from warning * fix latest clippy * clippy fixes++ * renamed shmem parameters * renamed map to shmem * make forkserver executor work for any (non-system) shmem * Mem -> ShMem * rework windows * fix nit * fix symbolic * refacctor map observers * iterator for map observers * removed unused ownedptr, added asslice trait to most functions * make map entry type an associated type * fix fuzzers * fix docs * typo fix * fix windows, add try_from_slice to shmid * missing import * fix fuzzbench * cleanup * fmt * more asslice * fmt * added doc link about token-level fuzzing * cods
This commit is contained in:
parent
b67a7f5b60
commit
77e5965e97
@ -77,7 +77,10 @@ To start, we create the closure that we want to fuzz. It takes a buffer as input
|
|||||||
|
|
||||||
```rust
|
```rust
|
||||||
extern crate libafl;
|
extern crate libafl;
|
||||||
use libafl::inputs::{BytesInput, HasTargetBytes};
|
use libafl::{
|
||||||
|
bolts::AsSlice,
|
||||||
|
inputs::{BytesInput, HasTargetBytes},
|
||||||
|
};
|
||||||
|
|
||||||
let mut harness = |input: &BytesInput| {
|
let mut harness = |input: &BytesInput| {
|
||||||
let target = input.target_bytes();
|
let target = input.target_bytes();
|
||||||
@ -218,6 +221,7 @@ As we don't rely on any instrumentation engine, we have to manually track the sa
|
|||||||
```rust
|
```rust
|
||||||
extern crate libafl;
|
extern crate libafl;
|
||||||
use libafl::{
|
use libafl::{
|
||||||
|
bolts::AsSlice,
|
||||||
inputs::{BytesInput, HasTargetBytes},
|
inputs::{BytesInput, HasTargetBytes},
|
||||||
executors::ExitKind,
|
executors::ExitKind,
|
||||||
};
|
};
|
||||||
|
@ -4,7 +4,7 @@ use std::path::PathBuf;
|
|||||||
use std::ptr::write_volatile;
|
use std::ptr::write_volatile;
|
||||||
|
|
||||||
use libafl::{
|
use libafl::{
|
||||||
bolts::{current_nanos, rands::StdRand, tuples::tuple_list},
|
bolts::{current_nanos, rands::StdRand, tuples::tuple_list, AsSlice},
|
||||||
corpus::{InMemoryCorpus, OnDiskCorpus, QueueCorpusScheduler},
|
corpus::{InMemoryCorpus, OnDiskCorpus, QueueCorpusScheduler},
|
||||||
events::SimpleEventManager,
|
events::SimpleEventManager,
|
||||||
executors::{inprocess::InProcessExecutor, ExitKind},
|
executors::{inprocess::InProcessExecutor, ExitKind},
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#![cfg_attr(not(any(windows, unix)), feature(default_alloc_error_handler))]
|
#![cfg_attr(not(any(windows, unix)), feature(default_alloc_error_handler))]
|
||||||
|
|
||||||
use libafl::{
|
use libafl::{
|
||||||
bolts::{current_nanos, rands::StdRand, tuples::tuple_list},
|
bolts::{current_nanos, rands::StdRand, tuples::tuple_list, AsSlice},
|
||||||
corpus::{InMemoryCorpus, QueueCorpusScheduler},
|
corpus::{InMemoryCorpus, QueueCorpusScheduler},
|
||||||
events::SimpleEventManager,
|
events::SimpleEventManager,
|
||||||
executors::{inprocess::InProcessExecutor, ExitKind},
|
executors::{inprocess::InProcessExecutor, ExitKind},
|
||||||
|
@ -5,6 +5,7 @@ use libafl::{
|
|||||||
rands::StdRand,
|
rands::StdRand,
|
||||||
shmem::{ShMem, ShMemProvider, StdShMemProvider},
|
shmem::{ShMem, ShMemProvider, StdShMemProvider},
|
||||||
tuples::tuple_list,
|
tuples::tuple_list,
|
||||||
|
AsMutSlice,
|
||||||
},
|
},
|
||||||
corpus::{
|
corpus::{
|
||||||
Corpus, InMemoryCorpus, IndexesLenTimeMinimizerCorpusScheduler, OnDiskCorpus,
|
Corpus, InMemoryCorpus, IndexesLenTimeMinimizerCorpusScheduler, OnDiskCorpus,
|
||||||
|
@ -20,6 +20,7 @@ use libafl::{
|
|||||||
rands::StdRand,
|
rands::StdRand,
|
||||||
shmem::{ShMemProvider, StdShMemProvider},
|
shmem::{ShMemProvider, StdShMemProvider},
|
||||||
tuples::{tuple_list, Merge},
|
tuples::{tuple_list, Merge},
|
||||||
|
AsSlice,
|
||||||
},
|
},
|
||||||
corpus::{
|
corpus::{
|
||||||
ondisk::OnDiskMetadataFormat, CachedOnDiskCorpus, Corpus,
|
ondisk::OnDiskMetadataFormat, CachedOnDiskCorpus, Corpus,
|
||||||
|
@ -24,6 +24,7 @@ use libafl::{
|
|||||||
rands::StdRand,
|
rands::StdRand,
|
||||||
shmem::{ShMemProvider, StdShMemProvider},
|
shmem::{ShMemProvider, StdShMemProvider},
|
||||||
tuples::{tuple_list, Merge},
|
tuples::{tuple_list, Merge},
|
||||||
|
AsSlice,
|
||||||
},
|
},
|
||||||
corpus::{
|
corpus::{
|
||||||
Corpus, IndexesLenTimeMinimizerCorpusScheduler, OnDiskCorpus, PowerQueueCorpusScheduler,
|
Corpus, IndexesLenTimeMinimizerCorpusScheduler, OnDiskCorpus, PowerQueueCorpusScheduler,
|
||||||
|
@ -21,6 +21,7 @@ use libafl::{
|
|||||||
rands::StdRand,
|
rands::StdRand,
|
||||||
shmem::{ShMemProvider, StdShMemProvider},
|
shmem::{ShMemProvider, StdShMemProvider},
|
||||||
tuples::{tuple_list, Merge},
|
tuples::{tuple_list, Merge},
|
||||||
|
AsSlice,
|
||||||
},
|
},
|
||||||
corpus::{
|
corpus::{
|
||||||
Corpus, IndexesLenTimeMinimizerCorpusScheduler, OnDiskCorpus, PowerQueueCorpusScheduler,
|
Corpus, IndexesLenTimeMinimizerCorpusScheduler, OnDiskCorpus, PowerQueueCorpusScheduler,
|
||||||
|
@ -16,6 +16,7 @@ use libafl::{
|
|||||||
rands::StdRand,
|
rands::StdRand,
|
||||||
shmem::{ShMemProvider, StdShMemProvider},
|
shmem::{ShMemProvider, StdShMemProvider},
|
||||||
tuples::{tuple_list, Merge},
|
tuples::{tuple_list, Merge},
|
||||||
|
AsSlice,
|
||||||
},
|
},
|
||||||
corpus::{
|
corpus::{
|
||||||
Corpus, InMemoryCorpus, IndexesLenTimeMinimizerCorpusScheduler, OnDiskCorpus,
|
Corpus, InMemoryCorpus, IndexesLenTimeMinimizerCorpusScheduler, OnDiskCorpus,
|
||||||
|
@ -19,6 +19,7 @@ use libafl::{
|
|||||||
rands::StdRand,
|
rands::StdRand,
|
||||||
shmem::{ShMemProvider, StdShMemProvider},
|
shmem::{ShMemProvider, StdShMemProvider},
|
||||||
tuples::{tuple_list, Merge},
|
tuples::{tuple_list, Merge},
|
||||||
|
AsSlice,
|
||||||
},
|
},
|
||||||
corpus::{
|
corpus::{
|
||||||
Corpus, InMemoryCorpus, IndexesLenTimeMinimizerCorpusScheduler, OnDiskCorpus,
|
Corpus, InMemoryCorpus, IndexesLenTimeMinimizerCorpusScheduler, OnDiskCorpus,
|
||||||
|
@ -11,6 +11,7 @@ use libafl::{
|
|||||||
current_nanos,
|
current_nanos,
|
||||||
rands::StdRand,
|
rands::StdRand,
|
||||||
tuples::{tuple_list, Merge},
|
tuples::{tuple_list, Merge},
|
||||||
|
AsSlice,
|
||||||
},
|
},
|
||||||
corpus::{Corpus, InMemoryCorpus, OnDiskCorpus, RandCorpusScheduler},
|
corpus::{Corpus, InMemoryCorpus, OnDiskCorpus, RandCorpusScheduler},
|
||||||
events::{setup_restarting_mgr_std, EventConfig},
|
events::{setup_restarting_mgr_std, EventConfig},
|
||||||
|
@ -12,6 +12,7 @@ use libafl::{
|
|||||||
current_nanos,
|
current_nanos,
|
||||||
rands::StdRand,
|
rands::StdRand,
|
||||||
tuples::{tuple_list, Merge},
|
tuples::{tuple_list, Merge},
|
||||||
|
AsSlice,
|
||||||
},
|
},
|
||||||
corpus::{
|
corpus::{
|
||||||
Corpus, InMemoryCorpus, IndexesLenTimeMinimizerCorpusScheduler, OnDiskCorpus,
|
Corpus, InMemoryCorpus, IndexesLenTimeMinimizerCorpusScheduler, OnDiskCorpus,
|
||||||
|
@ -18,6 +18,7 @@ use libafl::{
|
|||||||
rands::StdRand,
|
rands::StdRand,
|
||||||
shmem::{ShMemProvider, StdShMemProvider},
|
shmem::{ShMemProvider, StdShMemProvider},
|
||||||
tuples::{tuple_list, Merge},
|
tuples::{tuple_list, Merge},
|
||||||
|
AsSlice,
|
||||||
},
|
},
|
||||||
corpus::{
|
corpus::{
|
||||||
Corpus, InMemoryCorpus, IndexesLenTimeMinimizerCorpusScheduler, OnDiskCorpus,
|
Corpus, InMemoryCorpus, IndexesLenTimeMinimizerCorpusScheduler, OnDiskCorpus,
|
||||||
|
@ -18,6 +18,7 @@ use libafl::{
|
|||||||
rands::StdRand,
|
rands::StdRand,
|
||||||
shmem::{ShMemProvider, StdShMemProvider},
|
shmem::{ShMemProvider, StdShMemProvider},
|
||||||
tuples::{tuple_list, Merge},
|
tuples::{tuple_list, Merge},
|
||||||
|
AsSlice,
|
||||||
},
|
},
|
||||||
corpus::{
|
corpus::{
|
||||||
Corpus, InMemoryCorpus, IndexesLenTimeMinimizerCorpusScheduler, OnDiskCorpus,
|
Corpus, InMemoryCorpus, IndexesLenTimeMinimizerCorpusScheduler, OnDiskCorpus,
|
||||||
|
@ -7,7 +7,7 @@ static GLOBAL: MiMalloc = MiMalloc;
|
|||||||
use std::{env, path::PathBuf};
|
use std::{env, path::PathBuf};
|
||||||
|
|
||||||
use libafl::{
|
use libafl::{
|
||||||
bolts::{current_nanos, rands::StdRand, tuples::tuple_list},
|
bolts::{current_nanos, rands::StdRand, tuples::tuple_list, AsSlice},
|
||||||
corpus::{Corpus, InMemoryCorpus, OnDiskCorpus, RandCorpusScheduler},
|
corpus::{Corpus, InMemoryCorpus, OnDiskCorpus, RandCorpusScheduler},
|
||||||
events::{setup_restarting_mgr_std, EventConfig, EventRestarter},
|
events::{setup_restarting_mgr_std, EventConfig, EventRestarter},
|
||||||
executors::{inprocess::InProcessExecutor, ExitKind},
|
executors::{inprocess::InProcessExecutor, ExitKind},
|
||||||
|
@ -7,7 +7,7 @@ static GLOBAL: MiMalloc = MiMalloc;
|
|||||||
use std::{env, path::PathBuf};
|
use std::{env, path::PathBuf};
|
||||||
|
|
||||||
use libafl::{
|
use libafl::{
|
||||||
bolts::{current_nanos, rands::StdRand, tuples::tuple_list},
|
bolts::{current_nanos, rands::StdRand, tuples::tuple_list, AsSlice},
|
||||||
corpus::{
|
corpus::{
|
||||||
Corpus, InMemoryCorpus, IndexesLenTimeMinimizerCorpusScheduler, OnDiskCorpus,
|
Corpus, InMemoryCorpus, IndexesLenTimeMinimizerCorpusScheduler, OnDiskCorpus,
|
||||||
QueueCorpusScheduler,
|
QueueCorpusScheduler,
|
||||||
|
@ -4,7 +4,7 @@ use std::{
|
|||||||
env,
|
env,
|
||||||
io::{stdout, Write},
|
io::{stdout, Write},
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
process::{exit, Command},
|
process::exit,
|
||||||
};
|
};
|
||||||
|
|
||||||
use which::which;
|
use which::which;
|
||||||
|
@ -13,6 +13,7 @@ use libafl::{
|
|||||||
rands::StdRand,
|
rands::StdRand,
|
||||||
shmem::{ShMem, ShMemProvider, StdShMemProvider},
|
shmem::{ShMem, ShMemProvider, StdShMemProvider},
|
||||||
tuples::{tuple_list, Named},
|
tuples::{tuple_list, Named},
|
||||||
|
AsMutSlice, AsSlice,
|
||||||
},
|
},
|
||||||
corpus::{
|
corpus::{
|
||||||
Corpus, InMemoryCorpus, IndexesLenTimeMinimizerCorpusScheduler, OnDiskCorpus,
|
Corpus, InMemoryCorpus, IndexesLenTimeMinimizerCorpusScheduler, OnDiskCorpus,
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
use klo_routines::*;
|
use klo_routines::*;
|
||||||
use libafl::inputs::{BytesInput, HasTargetBytes};
|
use libafl::inputs::{BytesInput, HasTargetBytes};
|
||||||
use libafl::{
|
use libafl::{
|
||||||
bolts::{current_nanos, rands::StdRand, tuples::tuple_list},
|
bolts::{current_nanos, rands::StdRand, tuples::tuple_list, AsSlice},
|
||||||
corpus::{InMemoryCorpus, OnDiskCorpus, QueueCorpusScheduler},
|
corpus::{InMemoryCorpus, OnDiskCorpus, QueueCorpusScheduler},
|
||||||
events::SimpleEventManager,
|
events::SimpleEventManager,
|
||||||
executors::{inprocess::InProcessExecutor, ExitKind},
|
executors::{inprocess::InProcessExecutor, ExitKind},
|
||||||
|
@ -8,7 +8,7 @@ use core::cell::{Cell, RefCell};
|
|||||||
use std::{path::PathBuf, rc::Rc};
|
use std::{path::PathBuf, rc::Rc};
|
||||||
|
|
||||||
use libafl::{
|
use libafl::{
|
||||||
bolts::{current_nanos, rands::StdRand, tuples::tuple_list},
|
bolts::{current_nanos, rands::StdRand, tuples::tuple_list, AsSlice},
|
||||||
corpus::{
|
corpus::{
|
||||||
Corpus, CorpusScheduler, InMemoryCorpus, OnDiskCorpus, QueueCorpusScheduler, Testcase,
|
Corpus, CorpusScheduler, InMemoryCorpus, OnDiskCorpus, QueueCorpusScheduler, Testcase,
|
||||||
},
|
},
|
||||||
|
@ -11,6 +11,7 @@ use libafl::{
|
|||||||
rands::StdRand,
|
rands::StdRand,
|
||||||
shmem::{ShMemProvider, StdShMemProvider},
|
shmem::{ShMemProvider, StdShMemProvider},
|
||||||
tuples::tuple_list,
|
tuples::tuple_list,
|
||||||
|
AsSlice,
|
||||||
},
|
},
|
||||||
corpus::{
|
corpus::{
|
||||||
Corpus, InMemoryCorpus, IndexesLenTimeMinimizerCorpusScheduler, OnDiskCorpus,
|
Corpus, InMemoryCorpus, IndexesLenTimeMinimizerCorpusScheduler, OnDiskCorpus,
|
||||||
|
@ -7,7 +7,7 @@ use core::time::Duration;
|
|||||||
use std::{env, path::PathBuf};
|
use std::{env, path::PathBuf};
|
||||||
|
|
||||||
use libafl::{
|
use libafl::{
|
||||||
bolts::{current_nanos, rands::StdRand, tuples::tuple_list},
|
bolts::{current_nanos, rands::StdRand, tuples::tuple_list, AsSlice},
|
||||||
corpus::{Corpus, InMemoryCorpus, OnDiskCorpus, PowerQueueCorpusScheduler},
|
corpus::{Corpus, InMemoryCorpus, OnDiskCorpus, PowerQueueCorpusScheduler},
|
||||||
events::{setup_restarting_mgr_std, EventConfig, EventRestarter},
|
events::{setup_restarting_mgr_std, EventConfig, EventRestarter},
|
||||||
executors::{inprocess::InProcessExecutor, ExitKind, TimeoutExecutor},
|
executors::{inprocess::InProcessExecutor, ExitKind, TimeoutExecutor},
|
||||||
|
@ -542,7 +542,7 @@ impl LlmpMsg {
|
|||||||
|
|
||||||
/// Gets the buffer from this message as slice, with the corrent length.
|
/// Gets the buffer from this message as slice, with the corrent length.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn as_slice<SHM: ShMem>(&self, map: &mut LlmpSharedMap<SHM>) -> Result<&[u8], Error> {
|
pub fn try_as_slice<SHM: ShMem>(&self, map: &mut LlmpSharedMap<SHM>) -> Result<&[u8], Error> {
|
||||||
unsafe {
|
unsafe {
|
||||||
if self.in_shmem(map) {
|
if self.in_shmem(map) {
|
||||||
Ok(self.as_slice_unsafe())
|
Ok(self.as_slice_unsafe())
|
||||||
@ -1110,7 +1110,7 @@ where
|
|||||||
#[allow(clippy::cast_ptr_alignment)]
|
#[allow(clippy::cast_ptr_alignment)]
|
||||||
let mut end_of_page_msg = (*out).buf.as_mut_ptr() as *mut LlmpPayloadSharedMapInfo;
|
let mut end_of_page_msg = (*out).buf.as_mut_ptr() as *mut LlmpPayloadSharedMapInfo;
|
||||||
(*end_of_page_msg).map_size = new_map_shmem.shmem.len();
|
(*end_of_page_msg).map_size = new_map_shmem.shmem.len();
|
||||||
(*end_of_page_msg).shm_str = *new_map_shmem.shmem.id().as_slice();
|
(*end_of_page_msg).shm_str = *new_map_shmem.shmem.id().as_array();
|
||||||
|
|
||||||
/* Send the last msg on the old buf */
|
/* Send the last msg on the old buf */
|
||||||
self.send(out, true)?;
|
self.send(out, true)?;
|
||||||
@ -1439,7 +1439,7 @@ where
|
|||||||
// Map the new page. The old one should be unmapped by Drop
|
// Map the new page. The old one should be unmapped by Drop
|
||||||
self.current_recv_shmem =
|
self.current_recv_shmem =
|
||||||
LlmpSharedMap::existing(self.shmem_provider.shmem_from_id_and_size(
|
LlmpSharedMap::existing(self.shmem_provider.shmem_from_id_and_size(
|
||||||
ShMemId::from_slice(&pageinfo_cpy.shm_str),
|
ShMemId::from_array(&pageinfo_cpy.shm_str),
|
||||||
pageinfo_cpy.map_size,
|
pageinfo_cpy.map_size,
|
||||||
)?);
|
)?);
|
||||||
page = self.current_recv_shmem.page_mut();
|
page = self.current_recv_shmem.page_mut();
|
||||||
@ -1512,7 +1512,7 @@ where
|
|||||||
(*msg).sender,
|
(*msg).sender,
|
||||||
(*msg).tag,
|
(*msg).tag,
|
||||||
(*msg).flags,
|
(*msg).flags,
|
||||||
(*msg).as_slice(&mut self.current_recv_shmem)?,
|
(*msg).try_as_slice(&mut self.current_recv_shmem)?,
|
||||||
)),
|
)),
|
||||||
None => None,
|
None => None,
|
||||||
})
|
})
|
||||||
@ -1527,7 +1527,7 @@ where
|
|||||||
Ok((
|
Ok((
|
||||||
(*msg).sender,
|
(*msg).sender,
|
||||||
(*msg).tag,
|
(*msg).tag,
|
||||||
(*msg).as_slice(&mut self.current_recv_shmem)?,
|
(*msg).try_as_slice(&mut self.current_recv_shmem)?,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1997,7 +1997,7 @@ where
|
|||||||
(*msg).tag = LLMP_TAG_NEW_SHM_CLIENT;
|
(*msg).tag = LLMP_TAG_NEW_SHM_CLIENT;
|
||||||
#[allow(clippy::cast_ptr_alignment)]
|
#[allow(clippy::cast_ptr_alignment)]
|
||||||
let pageinfo = (*msg).buf.as_mut_ptr() as *mut LlmpPayloadSharedMapInfo;
|
let pageinfo = (*msg).buf.as_mut_ptr() as *mut LlmpPayloadSharedMapInfo;
|
||||||
(*pageinfo).shm_str = *shmem_description.id.as_slice();
|
(*pageinfo).shm_str = *shmem_description.id.as_array();
|
||||||
(*pageinfo).map_size = shmem_description.size;
|
(*pageinfo).map_size = shmem_description.size;
|
||||||
sender.send(msg, true)
|
sender.send(msg, true)
|
||||||
}
|
}
|
||||||
@ -2329,7 +2329,7 @@ where
|
|||||||
let pageinfo = (*msg).buf.as_mut_ptr() as *mut LlmpPayloadSharedMapInfo;
|
let pageinfo = (*msg).buf.as_mut_ptr() as *mut LlmpPayloadSharedMapInfo;
|
||||||
|
|
||||||
match self.shmem_provider.shmem_from_id_and_size(
|
match self.shmem_provider.shmem_from_id_and_size(
|
||||||
ShMemId::from_slice(&(*pageinfo).shm_str),
|
ShMemId::from_array(&(*pageinfo).shm_str),
|
||||||
(*pageinfo).map_size,
|
(*pageinfo).map_size,
|
||||||
) {
|
) {
|
||||||
Ok(new_shmem) => {
|
Ok(new_shmem) => {
|
||||||
@ -2363,7 +2363,7 @@ where
|
|||||||
let mut should_forward_msg = true;
|
let mut should_forward_msg = true;
|
||||||
|
|
||||||
let map = &mut self.llmp_clients[client_id as usize].current_recv_shmem;
|
let map = &mut self.llmp_clients[client_id as usize].current_recv_shmem;
|
||||||
let msg_buf = (*msg).as_slice(map)?;
|
let msg_buf = (*msg).try_as_slice(map)?;
|
||||||
if let LlmpMsgHookResult::Handled =
|
if let LlmpMsgHookResult::Handled =
|
||||||
(on_new_msg)(client_id, (*msg).tag, (*msg).flags, msg_buf)?
|
(on_new_msg)(client_id, (*msg).tag, (*msg).flags, msg_buf)?
|
||||||
{
|
{
|
||||||
|
@ -30,6 +30,12 @@ pub trait AsSlice<T> {
|
|||||||
fn as_slice(&self) -> &[T];
|
fn as_slice(&self) -> &[T];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Can be converted to a mutable slice
|
||||||
|
pub trait AsMutSlice<T> {
|
||||||
|
/// Convert to a slice
|
||||||
|
fn as_mut_slice(&mut self) -> &mut [T];
|
||||||
|
}
|
||||||
|
|
||||||
/// Has a length field
|
/// Has a length field
|
||||||
pub trait HasLen {
|
pub trait HasLen {
|
||||||
/// The length
|
/// The length
|
||||||
|
@ -6,7 +6,10 @@ and forwards them over unix domain sockets.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
bolts::shmem::{ShMem, ShMemDescription, ShMemId, ShMemProvider},
|
bolts::{
|
||||||
|
shmem::{ShMem, ShMemDescription, ShMemId, ShMemProvider},
|
||||||
|
AsMutSlice, AsSlice,
|
||||||
|
},
|
||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
use core::{mem::ManuallyDrop, ptr::addr_of};
|
use core::{mem::ManuallyDrop, ptr::addr_of};
|
||||||
@ -88,11 +91,20 @@ where
|
|||||||
fn len(&self) -> usize {
|
fn len(&self) -> usize {
|
||||||
self.inner.len()
|
self.inner.len()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<SH> AsSlice<u8> for ServedShMem<SH>
|
||||||
|
where
|
||||||
|
SH: ShMem,
|
||||||
|
{
|
||||||
fn as_slice(&self) -> &[u8] {
|
fn as_slice(&self) -> &[u8] {
|
||||||
self.inner.as_slice()
|
self.inner.as_slice()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
impl<SH> AsMutSlice<u8> for ServedShMem<SH>
|
||||||
|
where
|
||||||
|
SH: ShMem,
|
||||||
|
{
|
||||||
fn as_mut_slice(&mut self) -> &mut [u8] {
|
fn as_mut_slice(&mut self) -> &mut [u8] {
|
||||||
self.inner.as_mut_slice()
|
self.inner.as_mut_slice()
|
||||||
}
|
}
|
||||||
@ -124,7 +136,7 @@ where
|
|||||||
.recv_fds(&mut shm_slice, &mut fd_buf)
|
.recv_fds(&mut shm_slice, &mut fd_buf)
|
||||||
.expect("Did not receive a response");
|
.expect("Did not receive a response");
|
||||||
|
|
||||||
let server_id = ShMemId::from_slice(&shm_slice);
|
let server_id = ShMemId::from_array(&shm_slice);
|
||||||
let server_fd: i32 = server_id.into();
|
let server_fd: i32 = server_id.into();
|
||||||
Ok((server_fd, fd_buf[0]))
|
Ok((server_fd, fd_buf[0]))
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,12 @@
|
|||||||
//! Wrappers that abstracts references (or pointers) and owned data accesses.
|
//! Wrappers that abstracts references (or pointers) and owned data accesses.
|
||||||
// The serialization is towards owned, allowing to serialize pointers without troubles.
|
// The serialization is towards owned, allowing to serialize pointers without troubles.
|
||||||
|
|
||||||
use alloc::{boxed::Box, vec::Vec};
|
use crate::bolts::{AsMutSlice, AsSlice};
|
||||||
|
use alloc::{
|
||||||
|
boxed::Box,
|
||||||
|
slice::{Iter, IterMut},
|
||||||
|
vec::Vec,
|
||||||
|
};
|
||||||
use core::{clone::Clone, fmt::Debug, slice};
|
use core::{clone::Clone, fmt::Debug, slice};
|
||||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||||
|
|
||||||
@ -234,6 +239,15 @@ impl<'a, T> OwnedSlice<'a, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a, 'it, T> IntoIterator for &'it OwnedSlice<'a, T> {
|
||||||
|
type Item = <Iter<'it, T> as Iterator>::Item;
|
||||||
|
type IntoIter = Iter<'it, T>;
|
||||||
|
|
||||||
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
|
self.as_slice().iter()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Create a new [`OwnedSlice`] from a vector
|
/// Create a new [`OwnedSlice`] from a vector
|
||||||
impl<'a, T> From<Vec<T>> for OwnedSlice<'a, T> {
|
impl<'a, T> From<Vec<T>> for OwnedSlice<'a, T> {
|
||||||
fn from(vec: Vec<T>) -> Self {
|
fn from(vec: Vec<T>) -> Self {
|
||||||
@ -274,10 +288,10 @@ impl<'a, T> From<OwnedSliceMut<'a, T>> for OwnedSlice<'a, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: Sized> OwnedSlice<'a, T> {
|
impl<'a, T: Sized> AsSlice<T> for OwnedSlice<'a, T> {
|
||||||
/// Get the [`OwnedSlice`] as slice.
|
/// Get the [`OwnedSlice`] as slice.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn as_slice(&self) -> &[T] {
|
fn as_slice(&self) -> &[T] {
|
||||||
match &self.inner {
|
match &self.inner {
|
||||||
OwnedSliceInner::Ref(r) => r,
|
OwnedSliceInner::Ref(r) => r,
|
||||||
OwnedSliceInner::RefRaw(rr, len) => unsafe { slice::from_raw_parts(*rr, *len) },
|
OwnedSliceInner::RefRaw(rr, len) => unsafe { slice::from_raw_parts(*rr, *len) },
|
||||||
@ -361,6 +375,24 @@ pub struct OwnedSliceMut<'a, T: 'a + Sized> {
|
|||||||
inner: OwnedSliceMutInner<'a, T>,
|
inner: OwnedSliceMutInner<'a, T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a, 'it, T> IntoIterator for &'it mut OwnedSliceMut<'a, T> {
|
||||||
|
type Item = <IterMut<'it, T> as Iterator>::Item;
|
||||||
|
type IntoIter = IterMut<'it, T>;
|
||||||
|
|
||||||
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
|
self.as_mut_slice().iter_mut()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, 'it, T> IntoIterator for &'it OwnedSliceMut<'a, T> {
|
||||||
|
type Item = <Iter<'it, T> as Iterator>::Item;
|
||||||
|
type IntoIter = Iter<'it, T>;
|
||||||
|
|
||||||
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
|
self.as_slice().iter()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a, T: 'a + Sized> OwnedSliceMut<'a, T> {
|
impl<'a, T: 'a + Sized> OwnedSliceMut<'a, T> {
|
||||||
/// Create a new [`OwnedSliceMut`] from a raw pointer and length
|
/// Create a new [`OwnedSliceMut`] from a raw pointer and length
|
||||||
///
|
///
|
||||||
@ -382,20 +414,21 @@ impl<'a, T: 'a + Sized> OwnedSliceMut<'a, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: Sized> OwnedSliceMut<'a, T> {
|
impl<'a, T: Sized> AsSlice<T> for OwnedSliceMut<'a, T> {
|
||||||
/// Get the value as slice
|
/// Get the value as slice
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn as_slice(&self) -> &[T] {
|
fn as_slice(&self) -> &[T] {
|
||||||
match &self.inner {
|
match &self.inner {
|
||||||
OwnedSliceMutInner::RefRaw(rr, len) => unsafe { slice::from_raw_parts(*rr, *len) },
|
OwnedSliceMutInner::RefRaw(rr, len) => unsafe { slice::from_raw_parts(*rr, *len) },
|
||||||
OwnedSliceMutInner::Ref(r) => r,
|
OwnedSliceMutInner::Ref(r) => r,
|
||||||
OwnedSliceMutInner::Owned(v) => v.as_slice(),
|
OwnedSliceMutInner::Owned(v) => v.as_slice(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
impl<'a, T: Sized> AsMutSlice<T> for OwnedSliceMut<'a, T> {
|
||||||
/// Get the value as mut slice
|
/// Get the value as mut slice
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn as_mut_slice(&mut self) -> &mut [T] {
|
fn as_mut_slice(&mut self) -> &mut [T] {
|
||||||
match &mut self.inner {
|
match &mut self.inner {
|
||||||
OwnedSliceMutInner::RefRaw(rr, len) => unsafe { slice::from_raw_parts_mut(*rr, *len) },
|
OwnedSliceMutInner::RefRaw(rr, len) => unsafe { slice::from_raw_parts_mut(*rr, *len) },
|
||||||
OwnedSliceMutInner::Ref(r) => r,
|
OwnedSliceMutInner::Ref(r) => r,
|
||||||
@ -608,140 +641,3 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Wrap a C-style pointer to an array (with size) and convert to a Vec on serialize
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub enum OwnedArrayPtr<T: Sized> {
|
|
||||||
/// Ptr to a slice
|
|
||||||
ArrayPtr((*const T, usize)),
|
|
||||||
/// A owned [`Vec`].
|
|
||||||
Owned(Vec<T>),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Sized + Serialize> Serialize for OwnedArrayPtr<T> {
|
|
||||||
fn serialize<S>(&self, se: S) -> Result<S::Ok, S::Error>
|
|
||||||
where
|
|
||||||
S: Serializer,
|
|
||||||
{
|
|
||||||
self.as_slice().serialize(se)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'de, T: Sized + Serialize> Deserialize<'de> for OwnedArrayPtr<T>
|
|
||||||
where
|
|
||||||
Vec<T>: Deserialize<'de>,
|
|
||||||
{
|
|
||||||
fn deserialize<D>(de: D) -> Result<Self, D::Error>
|
|
||||||
where
|
|
||||||
D: Deserializer<'de>,
|
|
||||||
{
|
|
||||||
Deserialize::deserialize(de).map(OwnedArrayPtr::Owned)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Sized> OwnedArrayPtr<T> {
|
|
||||||
/// Get a slice from this array.
|
|
||||||
#[must_use]
|
|
||||||
pub fn as_slice(&self) -> &[T] {
|
|
||||||
match self {
|
|
||||||
OwnedArrayPtr::ArrayPtr(p) => unsafe { core::slice::from_raw_parts(p.0, p.1) },
|
|
||||||
OwnedArrayPtr::Owned(v) => v.as_slice(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> IntoOwned for OwnedArrayPtr<T>
|
|
||||||
where
|
|
||||||
T: Sized + Clone,
|
|
||||||
{
|
|
||||||
#[must_use]
|
|
||||||
fn is_owned(&self) -> bool {
|
|
||||||
match self {
|
|
||||||
OwnedArrayPtr::ArrayPtr(_) => false,
|
|
||||||
OwnedArrayPtr::Owned(_) => true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[must_use]
|
|
||||||
fn into_owned(self) -> Self {
|
|
||||||
match self {
|
|
||||||
OwnedArrayPtr::ArrayPtr(p) => unsafe {
|
|
||||||
OwnedArrayPtr::Owned(core::slice::from_raw_parts(p.0, p.1).to_vec())
|
|
||||||
},
|
|
||||||
OwnedArrayPtr::Owned(v) => OwnedArrayPtr::Owned(v),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Wrap a C-style mutable pointer to an array (with size) and convert to a Vec on serialize
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub enum OwnedArrayPtrMut<T: Sized> {
|
|
||||||
/// A ptr to the array (or slice).
|
|
||||||
ArrayPtr((*mut T, usize)),
|
|
||||||
/// An owned [`Vec`].
|
|
||||||
Owned(Vec<T>),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Sized + Serialize> Serialize for OwnedArrayPtrMut<T> {
|
|
||||||
fn serialize<S>(&self, se: S) -> Result<S::Ok, S::Error>
|
|
||||||
where
|
|
||||||
S: Serializer,
|
|
||||||
{
|
|
||||||
self.as_slice().serialize(se)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'de, T: Sized + Serialize> Deserialize<'de> for OwnedArrayPtrMut<T>
|
|
||||||
where
|
|
||||||
Vec<T>: Deserialize<'de>,
|
|
||||||
{
|
|
||||||
fn deserialize<D>(de: D) -> Result<Self, D::Error>
|
|
||||||
where
|
|
||||||
D: Deserializer<'de>,
|
|
||||||
{
|
|
||||||
Deserialize::deserialize(de).map(OwnedArrayPtrMut::Owned)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Sized> OwnedArrayPtrMut<T> {
|
|
||||||
/// Return this array as slice
|
|
||||||
#[must_use]
|
|
||||||
pub fn as_slice(&self) -> &[T] {
|
|
||||||
match self {
|
|
||||||
OwnedArrayPtrMut::ArrayPtr(p) => unsafe { core::slice::from_raw_parts(p.0, p.1) },
|
|
||||||
OwnedArrayPtrMut::Owned(v) => v.as_slice(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return this array as mut slice
|
|
||||||
#[must_use]
|
|
||||||
pub fn as_mut_slice(&mut self) -> &mut [T] {
|
|
||||||
match self {
|
|
||||||
OwnedArrayPtrMut::ArrayPtr(p) => unsafe { core::slice::from_raw_parts_mut(p.0, p.1) },
|
|
||||||
OwnedArrayPtrMut::Owned(v) => v.as_mut_slice(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> IntoOwned for OwnedArrayPtrMut<T>
|
|
||||||
where
|
|
||||||
T: Sized + Clone,
|
|
||||||
{
|
|
||||||
#[must_use]
|
|
||||||
fn is_owned(&self) -> bool {
|
|
||||||
match self {
|
|
||||||
OwnedArrayPtrMut::ArrayPtr(_) => false,
|
|
||||||
OwnedArrayPtrMut::Owned(_) => true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[must_use]
|
|
||||||
fn into_owned(self) -> Self {
|
|
||||||
match self {
|
|
||||||
OwnedArrayPtrMut::ArrayPtr(p) => unsafe {
|
|
||||||
OwnedArrayPtrMut::Owned(core::slice::from_raw_parts(p.0, p.1).to_vec())
|
|
||||||
},
|
|
||||||
OwnedArrayPtrMut::Owned(v) => OwnedArrayPtrMut::Owned(v),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -3,7 +3,10 @@
|
|||||||
|
|
||||||
#[cfg(all(unix, feature = "std"))]
|
#[cfg(all(unix, feature = "std"))]
|
||||||
use crate::bolts::os::pipes::Pipe;
|
use crate::bolts::os::pipes::Pipe;
|
||||||
use crate::Error;
|
use crate::{
|
||||||
|
bolts::{AsMutSlice, AsSlice},
|
||||||
|
Error,
|
||||||
|
};
|
||||||
use alloc::{rc::Rc, string::ToString};
|
use alloc::{rc::Rc, string::ToString};
|
||||||
use core::{
|
use core::{
|
||||||
cell::RefCell,
|
cell::RefCell,
|
||||||
@ -89,10 +92,17 @@ pub struct ShMemId {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ShMemId {
|
impl ShMemId {
|
||||||
/// Create a new id from a fixed-size string
|
/// Create a new id from a fixed-size string/bytes array
|
||||||
|
/// It should contain a valid cstring.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn from_slice(slice: &[u8; 20]) -> Self {
|
pub fn from_array(array: &[u8; 20]) -> Self {
|
||||||
Self { id: *slice }
|
Self { id: *array }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Try to create a new id from a bytes string.
|
||||||
|
/// The slice must have a length of at least 20 bytes and contain a valid cstring.
|
||||||
|
pub fn try_from_slice(slice: &[u8]) -> Result<Self, Error> {
|
||||||
|
Ok(Self::from_array(&slice[0..20].try_into()?))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new id from an int
|
/// Create a new id from an int
|
||||||
@ -113,7 +123,7 @@ impl ShMemId {
|
|||||||
|
|
||||||
/// Get the id as a fixed-length slice
|
/// Get the id as a fixed-length slice
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn as_slice(&self) -> &[u8; 20] {
|
pub fn as_array(&self) -> &[u8; 20] {
|
||||||
&self.id
|
&self.id
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,6 +139,11 @@ impl ShMemId {
|
|||||||
alloc::str::from_utf8(&self.id[..self.null_pos()]).unwrap()
|
alloc::str::from_utf8(&self.id[..self.null_pos()]).unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl AsSlice<u8> for ShMemId {
|
||||||
|
fn as_slice(&self) -> &[u8] {
|
||||||
|
&self.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<ShMemId> for i32 {
|
impl From<ShMemId> for i32 {
|
||||||
fn from(id: ShMemId) -> i32 {
|
fn from(id: ShMemId) -> i32 {
|
||||||
@ -145,7 +160,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::bolts::llmp`] for inter-process communication.
|
/// They are the backbone of [`crate::bolts::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 {
|
pub trait ShMem: Sized + Debug + Clone + AsSlice<u8> + AsMutSlice<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;
|
||||||
|
|
||||||
@ -165,12 +180,6 @@ pub trait ShMem: Sized + Debug + Clone {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The actual shared map, in memory
|
|
||||||
fn as_slice(&self) -> &[u8];
|
|
||||||
|
|
||||||
/// The actual shared map, mutable
|
|
||||||
fn as_mut_slice(&mut self) -> &mut [u8];
|
|
||||||
|
|
||||||
/// Write this map's config to env
|
/// Write this map's config to env
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
fn write_to_env(&self, env_name: &str) -> Result<(), Error> {
|
fn write_to_env(&self, env_name: &str) -> Result<(), Error> {
|
||||||
@ -264,11 +273,21 @@ where
|
|||||||
fn len(&self) -> usize {
|
fn len(&self) -> usize {
|
||||||
self.internal.len()
|
self.internal.len()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> AsSlice<u8> for RcShMem<T>
|
||||||
|
where
|
||||||
|
T: ShMemProvider + Debug,
|
||||||
|
{
|
||||||
fn as_slice(&self) -> &[u8] {
|
fn as_slice(&self) -> &[u8] {
|
||||||
self.internal.as_slice()
|
self.internal.as_slice()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> AsMutSlice<u8> for RcShMem<T>
|
||||||
|
where
|
||||||
|
T: ShMemProvider + Debug,
|
||||||
|
{
|
||||||
fn as_mut_slice(&mut self) -> &mut [u8] {
|
fn as_mut_slice(&mut self) -> &mut [u8] {
|
||||||
self.internal.as_mut_slice()
|
self.internal.as_mut_slice()
|
||||||
}
|
}
|
||||||
@ -489,7 +508,10 @@ pub mod unix_shmem {
|
|||||||
use std::{io::Write, process};
|
use std::{io::Write, process};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
bolts::shmem::{ShMem, ShMemId, ShMemProvider},
|
bolts::{
|
||||||
|
shmem::{ShMem, ShMemId, ShMemProvider},
|
||||||
|
AsMutSlice, AsSlice,
|
||||||
|
},
|
||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
@ -691,11 +713,15 @@ pub mod unix_shmem {
|
|||||||
fn len(&self) -> usize {
|
fn len(&self) -> usize {
|
||||||
self.map_size
|
self.map_size
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsSlice<u8> for MmapShMem {
|
||||||
fn as_slice(&self) -> &[u8] {
|
fn as_slice(&self) -> &[u8] {
|
||||||
unsafe { slice::from_raw_parts(self.map, self.map_size) }
|
unsafe { slice::from_raw_parts(self.map, self.map_size) }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsMutSlice<u8> for MmapShMem {
|
||||||
fn as_mut_slice(&mut self) -> &mut [u8] {
|
fn as_mut_slice(&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) }
|
||||||
}
|
}
|
||||||
@ -790,11 +816,15 @@ pub mod unix_shmem {
|
|||||||
fn len(&self) -> usize {
|
fn len(&self) -> usize {
|
||||||
self.map_size
|
self.map_size
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsSlice<u8> for CommonUnixShMem {
|
||||||
fn as_slice(&self) -> &[u8] {
|
fn as_slice(&self) -> &[u8] {
|
||||||
unsafe { slice::from_raw_parts(self.map, self.map_size) }
|
unsafe { slice::from_raw_parts(self.map, self.map_size) }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsMutSlice<u8> for CommonUnixShMem {
|
||||||
fn as_mut_slice(&mut self) -> &mut [u8] {
|
fn as_mut_slice(&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) }
|
||||||
}
|
}
|
||||||
@ -858,7 +888,10 @@ pub mod unix_shmem {
|
|||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
bolts::shmem::{ShMem, ShMemId, ShMemProvider},
|
bolts::{
|
||||||
|
shmem::{ShMem, ShMemId, ShMemProvider},
|
||||||
|
AsMutSlice, AsSlice,
|
||||||
|
},
|
||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -992,11 +1025,15 @@ pub mod unix_shmem {
|
|||||||
fn len(&self) -> usize {
|
fn len(&self) -> usize {
|
||||||
self.map_size
|
self.map_size
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsSlice<u8> for AshmemShMem {
|
||||||
fn as_slice(&self) -> &[u8] {
|
fn as_slice(&self) -> &[u8] {
|
||||||
unsafe { slice::from_raw_parts(self.map, self.map_size) }
|
unsafe { slice::from_raw_parts(self.map, self.map_size) }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsMutSlice<u8> for AshmemShMem {
|
||||||
fn as_mut_slice(&mut self) -> &mut [u8] {
|
fn as_mut_slice(&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) }
|
||||||
}
|
}
|
||||||
@ -1069,7 +1106,10 @@ pub mod unix_shmem {
|
|||||||
pub mod win32_shmem {
|
pub mod win32_shmem {
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
bolts::shmem::{ShMem, ShMemId, ShMemProvider},
|
bolts::{
|
||||||
|
shmem::{ShMem, ShMemId, ShMemProvider},
|
||||||
|
AsMutSlice, AsSlice,
|
||||||
|
},
|
||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1141,7 +1181,7 @@ pub mod win32_shmem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
id: ShMemId::from_slice(&map_str_bytes[0..20].try_into().unwrap()),
|
id: ShMemId::try_from_slice(&map_str_bytes).unwrap(),
|
||||||
handle,
|
handle,
|
||||||
map,
|
map,
|
||||||
map_size,
|
map_size,
|
||||||
@ -1189,11 +1229,14 @@ pub mod win32_shmem {
|
|||||||
fn len(&self) -> usize {
|
fn len(&self) -> usize {
|
||||||
self.map_size
|
self.map_size
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsSlice<u8> for Win32ShMem {
|
||||||
fn as_slice(&self) -> &[u8] {
|
fn as_slice(&self) -> &[u8] {
|
||||||
unsafe { slice::from_raw_parts(self.map, self.map_size) }
|
unsafe { slice::from_raw_parts(self.map, self.map_size) }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
impl AsMutSlice<u8> for Win32ShMem {
|
||||||
fn as_mut_slice(&mut self) -> &mut [u8] {
|
fn as_mut_slice(&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) }
|
||||||
}
|
}
|
||||||
@ -1348,7 +1391,10 @@ impl<T: ShMem> std::io::Seek for ShMemCursor<T> {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use serial_test::serial;
|
use serial_test::serial;
|
||||||
|
|
||||||
use crate::bolts::shmem::{ShMem, ShMemProvider, StdShMemProvider};
|
use crate::bolts::{
|
||||||
|
shmem::{ShMemProvider, StdShMemProvider},
|
||||||
|
AsMutSlice, AsSlice,
|
||||||
|
};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[serial]
|
#[serial]
|
||||||
|
@ -12,7 +12,10 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
bolts::shmem::{ShMem, ShMemProvider},
|
bolts::{
|
||||||
|
shmem::{ShMem, ShMemProvider},
|
||||||
|
AsSlice,
|
||||||
|
},
|
||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -105,7 +105,7 @@ where
|
|||||||
/// # Example
|
/// # Example
|
||||||
/// ```
|
/// ```
|
||||||
/// use std::{io::Write, process::{Stdio, Command, Child}};
|
/// use std::{io::Write, process::{Stdio, Command, Child}};
|
||||||
/// use libafl::{Error, inputs::{Input, HasTargetBytes}, executors::{Executor, command::CommandConfigurator}};
|
/// use libafl::{Error, bolts::AsSlice, inputs::{Input, HasTargetBytes}, executors::{Executor, command::CommandConfigurator}};
|
||||||
/// #[derive(Debug)]
|
/// #[derive(Debug)]
|
||||||
/// struct MyExecutor;
|
/// struct MyExecutor;
|
||||||
///
|
///
|
||||||
|
@ -19,6 +19,7 @@ use crate::{
|
|||||||
bolts::{
|
bolts::{
|
||||||
os::{dup2, pipes::Pipe},
|
os::{dup2, pipes::Pipe},
|
||||||
shmem::{ShMem, ShMemProvider, StdShMemProvider},
|
shmem::{ShMem, ShMemProvider, StdShMemProvider},
|
||||||
|
AsMutSlice, AsSlice,
|
||||||
},
|
},
|
||||||
executors::{Executor, ExitKind, HasObservers},
|
executors::{Executor, ExitKind, HasObservers},
|
||||||
inputs::{HasTargetBytes, Input},
|
inputs::{HasTargetBytes, Input},
|
||||||
@ -832,6 +833,7 @@ mod tests {
|
|||||||
bolts::{
|
bolts::{
|
||||||
shmem::{ShMem, ShMemProvider, StdShMemProvider},
|
shmem::{ShMem, ShMemProvider, StdShMemProvider},
|
||||||
tuples::tuple_list,
|
tuples::tuple_list,
|
||||||
|
AsMutSlice,
|
||||||
},
|
},
|
||||||
executors::ForkserverExecutor,
|
executors::ForkserverExecutor,
|
||||||
inputs::NopInput,
|
inputs::NopInput,
|
||||||
|
@ -32,6 +32,7 @@ pub mod command;
|
|||||||
pub use command::CommandExecutor;
|
pub use command::CommandExecutor;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
bolts::AsSlice,
|
||||||
inputs::{HasTargetBytes, Input},
|
inputs::{HasTargetBytes, Input},
|
||||||
observers::ObserversTuple,
|
observers::ObserversTuple,
|
||||||
Error,
|
Error,
|
||||||
|
@ -11,7 +11,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
use crate::{
|
use crate::{
|
||||||
bolts::{
|
bolts::{
|
||||||
tuples::{MatchName, Named},
|
tuples::{MatchName, Named},
|
||||||
AsSlice, HasRefCnt,
|
AsMutSlice, AsSlice, HasRefCnt,
|
||||||
},
|
},
|
||||||
corpus::Testcase,
|
corpus::Testcase,
|
||||||
events::{Event, EventFirer},
|
events::{Event, EventFirer},
|
||||||
@ -214,6 +214,12 @@ impl AsSlice<usize> for MapIndexesMetadata {
|
|||||||
self.list.as_slice()
|
self.list.as_slice()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl AsMutSlice<usize> for MapIndexesMetadata {
|
||||||
|
/// Convert to a slice
|
||||||
|
fn as_mut_slice(&mut self) -> &mut [usize] {
|
||||||
|
self.list.as_mut_slice()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl HasRefCnt for MapIndexesMetadata {
|
impl HasRefCnt for MapIndexesMetadata {
|
||||||
fn refcnt(&self) -> isize {
|
fn refcnt(&self) -> isize {
|
||||||
@ -249,6 +255,13 @@ impl AsSlice<usize> for MapNoveltiesMetadata {
|
|||||||
self.list.as_slice()
|
self.list.as_slice()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl AsMutSlice<usize> for MapNoveltiesMetadata {
|
||||||
|
/// Convert to a slice
|
||||||
|
#[must_use]
|
||||||
|
fn as_mut_slice(&mut self) -> &mut [usize] {
|
||||||
|
self.list.as_mut_slice()
|
||||||
|
}
|
||||||
|
}
|
||||||
impl MapNoveltiesMetadata {
|
impl MapNoveltiesMetadata {
|
||||||
/// Creates a new [`struct@MapNoveltiesMetadata`]
|
/// Creates a new [`struct@MapNoveltiesMetadata`]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
@ -308,7 +321,7 @@ where
|
|||||||
/// Create new `MapFeedbackState` for the observer type.
|
/// Create new `MapFeedbackState` for the observer type.
|
||||||
pub fn with_observer<O>(map_observer: &O) -> Self
|
pub fn with_observer<O>(map_observer: &O) -> Self
|
||||||
where
|
where
|
||||||
O: MapObserver<T>,
|
O: MapObserver<Entry = T>,
|
||||||
T: Debug,
|
T: Debug,
|
||||||
{
|
{
|
||||||
Self {
|
Self {
|
||||||
@ -335,7 +348,7 @@ pub struct MapFeedback<I, N, O, R, S, T>
|
|||||||
where
|
where
|
||||||
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||||
R: Reducer<T>,
|
R: Reducer<T>,
|
||||||
O: MapObserver<T>,
|
O: MapObserver,
|
||||||
N: IsNovel<T>,
|
N: IsNovel<T>,
|
||||||
S: HasFeedbackStates,
|
S: HasFeedbackStates,
|
||||||
{
|
{
|
||||||
@ -355,7 +368,7 @@ impl<I, N, O, R, S, T> Feedback<I, S> for MapFeedback<I, N, O, R, S, T>
|
|||||||
where
|
where
|
||||||
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||||
R: Reducer<T>,
|
R: Reducer<T>,
|
||||||
O: MapObserver<T>,
|
O: MapObserver<Entry = T>,
|
||||||
N: IsNovel<T>,
|
N: IsNovel<T>,
|
||||||
I: Input,
|
I: Input,
|
||||||
S: HasFeedbackStates + HasClientPerfMonitor + Debug,
|
S: HasFeedbackStates + HasClientPerfMonitor + Debug,
|
||||||
@ -464,7 +477,7 @@ where
|
|||||||
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||||
R: Reducer<T>,
|
R: Reducer<T>,
|
||||||
N: IsNovel<T>,
|
N: IsNovel<T>,
|
||||||
O: MapObserver<T>,
|
O: MapObserver,
|
||||||
S: HasFeedbackStates,
|
S: HasFeedbackStates,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -485,7 +498,7 @@ where
|
|||||||
+ Debug,
|
+ Debug,
|
||||||
R: Reducer<T>,
|
R: Reducer<T>,
|
||||||
N: IsNovel<T>,
|
N: IsNovel<T>,
|
||||||
O: MapObserver<T>,
|
O: MapObserver,
|
||||||
S: HasFeedbackStates,
|
S: HasFeedbackStates,
|
||||||
{
|
{
|
||||||
/// Create new `MapFeedback`
|
/// Create new `MapFeedback`
|
||||||
@ -557,7 +570,7 @@ pub struct ReachabilityFeedback<O> {
|
|||||||
|
|
||||||
impl<O> ReachabilityFeedback<O>
|
impl<O> ReachabilityFeedback<O>
|
||||||
where
|
where
|
||||||
O: MapObserver<usize>,
|
O: MapObserver<Entry = usize>,
|
||||||
{
|
{
|
||||||
/// Creates a new [`ReachabilityFeedback`] for a [`MapObserver`].
|
/// Creates a new [`ReachabilityFeedback`] for a [`MapObserver`].
|
||||||
#[must_use]
|
#[must_use]
|
||||||
@ -583,7 +596,7 @@ where
|
|||||||
impl<I, O, S> Feedback<I, S> for ReachabilityFeedback<O>
|
impl<I, O, S> Feedback<I, S> for ReachabilityFeedback<O>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
O: MapObserver<usize>,
|
O: MapObserver<Entry = usize>,
|
||||||
S: HasClientPerfMonitor,
|
S: HasClientPerfMonitor,
|
||||||
{
|
{
|
||||||
fn is_interesting<EM, OT>(
|
fn is_interesting<EM, OT>(
|
||||||
@ -632,7 +645,7 @@ where
|
|||||||
|
|
||||||
impl<O> Named for ReachabilityFeedback<O>
|
impl<O> Named for ReachabilityFeedback<O>
|
||||||
where
|
where
|
||||||
O: MapObserver<usize>,
|
O: MapObserver<Entry = usize>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn name(&self) -> &str {
|
fn name(&self) -> &str {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
//! The `EncodedInput` is the "normal" input, a map of codes, that can be sent directly to the client
|
//! The `EncodedInput` is the "normal" input, a map of codes, that can be sent directly to the client
|
||||||
//! (As opposed to other, more abstract, imputs, like an Grammar-Based AST Input)
|
//! (As opposed to other, more abstract, imputs, like an Grammar-Based AST Input)
|
||||||
|
//! See also [the paper on token-level fuzzing](https://www.usenix.org/system/files/sec21-salls.pdf)
|
||||||
|
|
||||||
use ahash::AHasher;
|
use ahash::AHasher;
|
||||||
use core::hash::Hasher;
|
use core::hash::Hasher;
|
||||||
|
@ -113,11 +113,11 @@ pub mod stats {
|
|||||||
pub use crate::monitors::UserStats;
|
pub use crate::monitors::UserStats;
|
||||||
}
|
}
|
||||||
|
|
||||||
use alloc::string::String;
|
use alloc::string::{FromUtf8Error, String};
|
||||||
use core::fmt;
|
use core::{array::TryFromSliceError, fmt, num::ParseIntError, num::TryFromIntError};
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use std::{env::VarError, io, num::ParseIntError, num::TryFromIntError, string::FromUtf8Error};
|
use std::{env::VarError, io};
|
||||||
|
|
||||||
/// Main error struct for AFL
|
/// Main error struct for AFL
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -209,10 +209,9 @@ impl From<io::Error> for Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
impl From<FromUtf8Error> for Error {
|
impl From<FromUtf8Error> for Error {
|
||||||
fn from(err: FromUtf8Error) -> Self {
|
fn from(err: FromUtf8Error) -> Self {
|
||||||
Self::Unknown(format!("Could not convert byte to utf-8: {:?}", err))
|
Self::Unknown(format!("Could not convert byte / utf-8: {:?}", err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -223,20 +222,24 @@ impl From<VarError> for Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
impl From<ParseIntError> for Error {
|
impl From<ParseIntError> for Error {
|
||||||
fn from(err: ParseIntError) -> Self {
|
fn from(err: ParseIntError) -> Self {
|
||||||
Self::Unknown(format!("Failed to parse Int: {:?}", err))
|
Self::Unknown(format!("Failed to parse Int: {:?}", err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
impl From<TryFromIntError> for Error {
|
impl From<TryFromIntError> for Error {
|
||||||
fn from(err: TryFromIntError) -> Self {
|
fn from(err: TryFromIntError) -> Self {
|
||||||
Self::IllegalState(format!("Expected conversion failed: {:?}", err))
|
Self::IllegalState(format!("Expected conversion failed: {:?}", err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<TryFromSliceError> for Error {
|
||||||
|
fn from(err: TryFromSliceError) -> Self {
|
||||||
|
Self::IllegalArgument(format!("Could not convert slice: {:?}", err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl std::error::Error for Error {}
|
impl std::error::Error for Error {}
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ use crate::{
|
|||||||
bolts::{
|
bolts::{
|
||||||
rands::Rand,
|
rands::Rand,
|
||||||
tuples::{tuple_list, tuple_list_type, NamedTuple},
|
tuples::{tuple_list, tuple_list_type, NamedTuple},
|
||||||
AsSlice,
|
AsMutSlice, AsSlice,
|
||||||
},
|
},
|
||||||
corpus::Corpus,
|
corpus::Corpus,
|
||||||
inputs::Input,
|
inputs::Input,
|
||||||
@ -33,10 +33,17 @@ pub struct LogMutationMetadata {
|
|||||||
crate::impl_serdeany!(LogMutationMetadata);
|
crate::impl_serdeany!(LogMutationMetadata);
|
||||||
|
|
||||||
impl AsSlice<String> for LogMutationMetadata {
|
impl AsSlice<String> for LogMutationMetadata {
|
||||||
|
#[must_use]
|
||||||
fn as_slice(&self) -> &[String] {
|
fn as_slice(&self) -> &[String] {
|
||||||
self.list.as_slice()
|
self.list.as_slice()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl AsMutSlice<String> for LogMutationMetadata {
|
||||||
|
#[must_use]
|
||||||
|
fn as_mut_slice(&mut self) -> &mut [String] {
|
||||||
|
self.list.as_mut_slice()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl LogMutationMetadata {
|
impl LogMutationMetadata {
|
||||||
/// Creates new [`struct@LogMutationMetadata`].
|
/// Creates new [`struct@LogMutationMetadata`].
|
||||||
|
@ -8,7 +8,7 @@ use core::fmt::Debug;
|
|||||||
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
bolts::{ownedref::OwnedRefMut, tuples::Named, AsSlice},
|
bolts::{ownedref::OwnedRefMut, tuples::Named, AsMutSlice, AsSlice},
|
||||||
observers::Observer,
|
observers::Observer,
|
||||||
state::HasMetadata,
|
state::HasMetadata,
|
||||||
Error,
|
Error,
|
||||||
@ -69,6 +69,13 @@ impl AsSlice<CmpValues> for CmpValuesMetadata {
|
|||||||
self.list.as_slice()
|
self.list.as_slice()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl AsMutSlice<CmpValues> for CmpValuesMetadata {
|
||||||
|
/// Convert to a slice
|
||||||
|
#[must_use]
|
||||||
|
fn as_mut_slice(&mut self) -> &mut [CmpValues] {
|
||||||
|
self.list.as_mut_slice()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl CmpValuesMetadata {
|
impl CmpValuesMetadata {
|
||||||
/// Creates a new [`struct@CmpValuesMetadata`]
|
/// Creates a new [`struct@CmpValuesMetadata`]
|
||||||
@ -111,10 +118,10 @@ where
|
|||||||
fn usable_count(&self) -> usize;
|
fn usable_count(&self) -> usize;
|
||||||
|
|
||||||
/// Get the `CmpMap`
|
/// Get the `CmpMap`
|
||||||
fn map(&self) -> &CM;
|
fn cmp_map(&self) -> &CM;
|
||||||
|
|
||||||
/// Get the `CmpMap` (mut)
|
/// Get the `CmpMap` (mut)
|
||||||
fn map_mut(&mut self) -> &mut CM;
|
fn cmp_map_mut(&mut self) -> &mut CM;
|
||||||
|
|
||||||
/// Add [`struct@CmpValuesMetadata`] to the State including the logged values.
|
/// Add [`struct@CmpValuesMetadata`] to the State including the logged values.
|
||||||
/// This routine does a basic loop filtering because loop index cmps are not interesting.
|
/// This routine does a basic loop filtering because loop index cmps are not interesting.
|
||||||
@ -132,7 +139,7 @@ where
|
|||||||
meta.list.clear();
|
meta.list.clear();
|
||||||
let count = self.usable_count();
|
let count = self.usable_count();
|
||||||
for i in 0..count {
|
for i in 0..count {
|
||||||
let execs = self.map().usable_executions_for(i);
|
let execs = self.cmp_map().usable_executions_for(i);
|
||||||
if execs > 0 {
|
if execs > 0 {
|
||||||
// Recongize loops and discard if needed
|
// Recongize loops and discard if needed
|
||||||
if execs > 4 {
|
if execs > 4 {
|
||||||
@ -143,7 +150,7 @@ where
|
|||||||
|
|
||||||
let mut last: Option<CmpValues> = None;
|
let mut last: Option<CmpValues> = None;
|
||||||
for j in 0..execs {
|
for j in 0..execs {
|
||||||
let val = self.map().values_of(i, j);
|
let val = self.cmp_map().values_of(i, j);
|
||||||
if let Some(l) = last.and_then(|x| x.to_u64_tuple()) {
|
if let Some(l) = last.and_then(|x| x.to_u64_tuple()) {
|
||||||
if let Some(v) = val.to_u64_tuple() {
|
if let Some(v) = val.to_u64_tuple() {
|
||||||
if l.0.wrapping_add(1) == v.0 {
|
if l.0.wrapping_add(1) == v.0 {
|
||||||
@ -173,7 +180,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for j in 0..execs {
|
for j in 0..execs {
|
||||||
meta.list.push(self.map().values_of(i, j));
|
meta.list.push(self.cmp_map().values_of(i, j));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -187,7 +194,7 @@ pub struct StdCmpObserver<'a, CM>
|
|||||||
where
|
where
|
||||||
CM: CmpMap + Serialize + DeserializeOwned,
|
CM: CmpMap + Serialize + DeserializeOwned,
|
||||||
{
|
{
|
||||||
map: OwnedRefMut<'a, CM>,
|
cmp_map: OwnedRefMut<'a, CM>,
|
||||||
size: Option<OwnedRefMut<'a, usize>>,
|
size: Option<OwnedRefMut<'a, usize>>,
|
||||||
name: String,
|
name: String,
|
||||||
}
|
}
|
||||||
@ -199,17 +206,17 @@ where
|
|||||||
/// Get the number of usable cmps (all by default)
|
/// Get the number of usable cmps (all by default)
|
||||||
fn usable_count(&self) -> usize {
|
fn usable_count(&self) -> usize {
|
||||||
match &self.size {
|
match &self.size {
|
||||||
None => self.map.as_ref().len(),
|
None => self.cmp_map.as_ref().len(),
|
||||||
Some(o) => *o.as_ref(),
|
Some(o) => *o.as_ref(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn map(&self) -> &CM {
|
fn cmp_map(&self) -> &CM {
|
||||||
self.map.as_ref()
|
self.cmp_map.as_ref()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn map_mut(&mut self) -> &mut CM {
|
fn cmp_map_mut(&mut self) -> &mut CM {
|
||||||
self.map.as_mut()
|
self.cmp_map.as_mut()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,7 +225,7 @@ where
|
|||||||
CM: CmpMap + Serialize + DeserializeOwned,
|
CM: CmpMap + Serialize + DeserializeOwned,
|
||||||
{
|
{
|
||||||
fn pre_exec(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> {
|
fn pre_exec(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> {
|
||||||
self.map.as_mut().reset()?;
|
self.cmp_map.as_mut().reset()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -242,7 +249,7 @@ where
|
|||||||
Self {
|
Self {
|
||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
size: None,
|
size: None,
|
||||||
map: OwnedRefMut::Ref(map),
|
cmp_map: OwnedRefMut::Ref(map),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -252,7 +259,7 @@ where
|
|||||||
Self {
|
Self {
|
||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
size: Some(OwnedRefMut::Ref(size)),
|
size: Some(OwnedRefMut::Ref(size)),
|
||||||
map: OwnedRefMut::Ref(map),
|
cmp_map: OwnedRefMut::Ref(map),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,12 @@ use alloc::{
|
|||||||
string::{String, ToString},
|
string::{String, ToString},
|
||||||
vec::Vec,
|
vec::Vec,
|
||||||
};
|
};
|
||||||
use core::{fmt::Debug, hash::Hasher, slice::from_raw_parts};
|
use core::{
|
||||||
|
fmt::Debug,
|
||||||
|
hash::Hasher,
|
||||||
|
iter::Flatten,
|
||||||
|
slice::{from_raw_parts, Iter, IterMut},
|
||||||
|
};
|
||||||
use intervaltree::IntervalTree;
|
use intervaltree::IntervalTree;
|
||||||
use num_traits::PrimInt;
|
use num_traits::PrimInt;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@ -14,41 +19,36 @@ use crate::{
|
|||||||
bolts::{
|
bolts::{
|
||||||
ownedref::{OwnedRefMut, OwnedSliceMut},
|
ownedref::{OwnedRefMut, OwnedSliceMut},
|
||||||
tuples::Named,
|
tuples::Named,
|
||||||
HasLen,
|
AsMutSlice, AsSlice, HasLen,
|
||||||
},
|
},
|
||||||
observers::Observer,
|
observers::Observer,
|
||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A [`MapObserver`] observes the static map, as oftentimes used for afl-like coverage information
|
/// Compute the hash of a slice
|
||||||
pub trait MapObserver<T>: HasLen + Named + Serialize + serde::de::DeserializeOwned + Debug
|
fn hash_slice<T: PrimInt>(slice: &[T]) -> u64 {
|
||||||
where
|
let mut hasher = AHasher::new_with_keys(0, 0);
|
||||||
T: PrimInt + Default + Copy + Debug,
|
let ptr = slice.as_ptr() as *const u8;
|
||||||
{
|
let map_size = slice.len() / core::mem::size_of::<T>();
|
||||||
/// Get the map if the observer can be represented with a slice
|
unsafe {
|
||||||
fn map(&self) -> Option<&[T]>;
|
hasher.write(from_raw_parts(ptr, map_size));
|
||||||
|
}
|
||||||
|
hasher.finish()
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the map (mutable) if the observer can be represented with a slice
|
/// A [`MapObserver`] observes the static map, as oftentimes used for afl-like coverage information
|
||||||
fn map_mut(&mut self) -> Option<&mut [T]>;
|
pub trait MapObserver: HasLen + Named + Serialize + serde::de::DeserializeOwned + Debug {
|
||||||
|
/// Type of each entry in this map
|
||||||
|
type Entry: PrimInt + Default + Copy + Debug;
|
||||||
|
|
||||||
/// Get the value at `idx`
|
/// Get the value at `idx`
|
||||||
fn get(&self, idx: usize) -> &T {
|
fn get(&self, idx: usize) -> &Self::Entry;
|
||||||
&self
|
|
||||||
.map()
|
|
||||||
.expect("Cannot get a map that cannot be represented as slice")[idx]
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the value at `idx` (mutable)
|
/// Get the value at `idx` (mutable)
|
||||||
fn get_mut(&mut self, idx: usize) -> &mut T {
|
fn get_mut(&mut self, idx: usize) -> &mut Self::Entry;
|
||||||
&mut self
|
|
||||||
.map_mut()
|
|
||||||
.expect("Cannot get a map that cannot be represented as slice")[idx]
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the number of usable entries in the map (all by default)
|
/// Get the number of usable entries in the map (all by default)
|
||||||
fn usable_count(&self) -> usize {
|
fn usable_count(&self) -> usize;
|
||||||
self.len()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Count the set bytes in the map
|
/// Count the set bytes in the map
|
||||||
fn count_bytes(&self) -> u64 {
|
fn count_bytes(&self) -> u64 {
|
||||||
@ -64,27 +64,16 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Compute the hash of the map
|
/// Compute the hash of the map
|
||||||
fn hash(&self) -> u64 {
|
fn hash(&self) -> u64;
|
||||||
let mut hasher = AHasher::new_with_keys(0, 0);
|
|
||||||
let slice = self
|
|
||||||
.map()
|
|
||||||
.expect("Cannot hash a map that cannot be represented as slice");
|
|
||||||
let ptr = slice.as_ptr() as *const u8;
|
|
||||||
let map_size = slice.len() / core::mem::size_of::<T>();
|
|
||||||
unsafe {
|
|
||||||
hasher.write(from_raw_parts(ptr, map_size));
|
|
||||||
}
|
|
||||||
hasher.finish()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the initial value for reset()
|
/// Get the initial value for reset()
|
||||||
fn initial(&self) -> T;
|
fn initial(&self) -> Self::Entry;
|
||||||
|
|
||||||
/// Get the initial value for reset()
|
/// Get the initial value for reset()
|
||||||
fn initial_mut(&mut self) -> &mut T;
|
fn initial_mut(&mut self) -> &mut Self::Entry;
|
||||||
|
|
||||||
/// Set the initial value for reset()
|
/// Set the initial value for reset()
|
||||||
fn set_initial(&mut self, initial: T);
|
fn set_initial(&mut self, initial: Self::Entry);
|
||||||
|
|
||||||
/// Reset the map
|
/// Reset the map
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -97,6 +86,16 @@ where
|
|||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get these observer's contents as [`Vec`]
|
||||||
|
fn to_vec(&self) -> Vec<Self::Entry> {
|
||||||
|
let cnt = self.usable_count();
|
||||||
|
let mut res = Vec::with_capacity(cnt);
|
||||||
|
for i in 0..cnt {
|
||||||
|
res.push(*self.get(i));
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The Map Observer retrieves the state of a map,
|
/// The Map Observer retrieves the state of a map,
|
||||||
@ -117,7 +116,7 @@ where
|
|||||||
impl<'a, I, S, T> Observer<I, S> for StdMapObserver<'a, T>
|
impl<'a, I, S, T> Observer<I, S> for StdMapObserver<'a, T>
|
||||||
where
|
where
|
||||||
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||||
Self: MapObserver<T>,
|
Self: MapObserver,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn pre_exec(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> {
|
fn pre_exec(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> {
|
||||||
@ -145,18 +144,53 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> MapObserver<T> for StdMapObserver<'a, T>
|
impl<'a, 'it, T> IntoIterator for &'it StdMapObserver<'a, T>
|
||||||
where
|
where
|
||||||
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||||
{
|
{
|
||||||
|
type Item = <Iter<'it, T> as Iterator>::Item;
|
||||||
|
type IntoIter = Iter<'it, T>;
|
||||||
|
|
||||||
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
|
self.as_slice().iter()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, 'it, T> IntoIterator for &'it mut StdMapObserver<'a, T>
|
||||||
|
where
|
||||||
|
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||||
|
{
|
||||||
|
type Item = <IterMut<'it, T> as Iterator>::Item;
|
||||||
|
type IntoIter = IterMut<'it, T>;
|
||||||
|
|
||||||
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
|
self.as_mut_slice().iter_mut()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T> MapObserver for StdMapObserver<'a, T>
|
||||||
|
where
|
||||||
|
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||||
|
{
|
||||||
|
type Entry = T;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn map(&self) -> Option<&[T]> {
|
fn get(&self, pos: usize) -> &T {
|
||||||
Some(self.map.as_slice())
|
&self.as_slice()[pos]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn map_mut(&mut self) -> Option<&mut [T]> {
|
fn get_mut(&mut self, idx: usize) -> &mut T {
|
||||||
Some(self.map.as_mut_slice())
|
&mut self.as_mut_slice()[idx]
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn usable_count(&self) -> usize {
|
||||||
|
self.as_slice().len()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn hash(&self) -> u64 {
|
||||||
|
hash_slice(self.as_slice())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -173,6 +207,31 @@ where
|
|||||||
fn set_initial(&mut self, initial: T) {
|
fn set_initial(&mut self, initial: T) {
|
||||||
self.initial = initial;
|
self.initial = initial;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn to_vec(&self) -> Vec<T> {
|
||||||
|
self.as_slice().to_vec()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T> AsSlice<T> for StdMapObserver<'a, T>
|
||||||
|
where
|
||||||
|
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||||
|
{
|
||||||
|
#[must_use]
|
||||||
|
#[inline]
|
||||||
|
fn as_slice(&self) -> &[T] {
|
||||||
|
self.map.as_slice()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<'a, T> AsMutSlice<T> for StdMapObserver<'a, T>
|
||||||
|
where
|
||||||
|
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||||
|
{
|
||||||
|
#[must_use]
|
||||||
|
#[inline]
|
||||||
|
fn as_mut_slice(&mut self) -> &mut [T] {
|
||||||
|
self.map.as_mut_slice()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> StdMapObserver<'a, T>
|
impl<'a, T> StdMapObserver<'a, T>
|
||||||
@ -251,7 +310,7 @@ where
|
|||||||
impl<'a, I, S, T, const N: usize> Observer<I, S> for ConstMapObserver<'a, T, N>
|
impl<'a, I, S, T, const N: usize> Observer<I, S> for ConstMapObserver<'a, T, N>
|
||||||
where
|
where
|
||||||
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||||
Self: MapObserver<T>,
|
Self: MapObserver,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn pre_exec(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> {
|
fn pre_exec(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> {
|
||||||
@ -279,24 +338,35 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T, const N: usize> MapObserver<T> for ConstMapObserver<'a, T, N>
|
impl<'a, 'it, T, const N: usize> IntoIterator for &'it ConstMapObserver<'a, T, N>
|
||||||
where
|
where
|
||||||
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||||
{
|
{
|
||||||
#[inline]
|
type Item = <Iter<'it, T> as Iterator>::Item;
|
||||||
fn usable_count(&self) -> usize {
|
type IntoIter = Iter<'it, T>;
|
||||||
N
|
|
||||||
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
|
self.as_slice().iter()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
impl<'a, 'it, T, const N: usize> IntoIterator for &'it mut ConstMapObserver<'a, T, N>
|
||||||
fn map(&self) -> Option<&[T]> {
|
where
|
||||||
Some(self.map.as_slice())
|
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||||
|
{
|
||||||
|
type Item = <IterMut<'it, T> as Iterator>::Item;
|
||||||
|
type IntoIter = IterMut<'it, T>;
|
||||||
|
|
||||||
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
|
self.as_mut_slice().iter_mut()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
impl<'a, T, const N: usize> MapObserver for ConstMapObserver<'a, T, N>
|
||||||
fn map_mut(&mut self) -> Option<&mut [T]> {
|
where
|
||||||
Some(self.map.as_mut_slice())
|
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||||
}
|
{
|
||||||
|
type Entry = T;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn initial(&self) -> T {
|
fn initial(&self) -> T {
|
||||||
@ -312,6 +382,47 @@ where
|
|||||||
fn set_initial(&mut self, initial: T) {
|
fn set_initial(&mut self, initial: T) {
|
||||||
self.initial = initial;
|
self.initial = initial;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn get(&self, idx: usize) -> &T {
|
||||||
|
&self.as_slice()[idx]
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn get_mut(&mut self, idx: usize) -> &mut T {
|
||||||
|
&mut self.as_mut_slice()[idx]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn usable_count(&self) -> usize {
|
||||||
|
self.as_slice().len()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn hash(&self) -> u64 {
|
||||||
|
hash_slice(self.as_slice())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_vec(&self) -> Vec<T> {
|
||||||
|
self.as_slice().to_vec()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T, const N: usize> AsSlice<T> for ConstMapObserver<'a, T, N>
|
||||||
|
where
|
||||||
|
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn as_slice(&self) -> &[T] {
|
||||||
|
self.map.as_slice()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<'a, T, const N: usize> AsMutSlice<T> for ConstMapObserver<'a, T, N>
|
||||||
|
where
|
||||||
|
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn as_mut_slice(&mut self) -> &mut [T] {
|
||||||
|
self.map.as_mut_slice()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T, const N: usize> ConstMapObserver<'a, T, N>
|
impl<'a, T, const N: usize> ConstMapObserver<'a, T, N>
|
||||||
@ -373,7 +484,7 @@ where
|
|||||||
impl<'a, I, S, T> Observer<I, S> for VariableMapObserver<'a, T>
|
impl<'a, I, S, T> Observer<I, S> for VariableMapObserver<'a, T>
|
||||||
where
|
where
|
||||||
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||||
Self: MapObserver<T>,
|
Self: MapObserver,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn pre_exec(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> {
|
fn pre_exec(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> {
|
||||||
@ -401,24 +512,35 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> MapObserver<T> for VariableMapObserver<'a, T>
|
impl<'a, 'it, T> IntoIterator for &'it VariableMapObserver<'a, T>
|
||||||
where
|
where
|
||||||
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||||
{
|
{
|
||||||
#[inline]
|
type Item = <Iter<'it, T> as Iterator>::Item;
|
||||||
fn map(&self) -> Option<&[T]> {
|
type IntoIter = Iter<'it, T>;
|
||||||
Some(self.map.as_slice())
|
|
||||||
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
|
self.as_slice().iter()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
impl<'a, 'it, T> IntoIterator for &'it mut VariableMapObserver<'a, T>
|
||||||
fn map_mut(&mut self) -> Option<&mut [T]> {
|
where
|
||||||
Some(self.map.as_mut_slice())
|
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||||
|
{
|
||||||
|
type Item = <IterMut<'it, T> as Iterator>::Item;
|
||||||
|
type IntoIter = IterMut<'it, T>;
|
||||||
|
|
||||||
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
|
self.as_mut_slice().iter_mut()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
impl<'a, T> MapObserver for VariableMapObserver<'a, T>
|
||||||
fn usable_count(&self) -> usize {
|
where
|
||||||
*self.size.as_ref()
|
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||||
}
|
{
|
||||||
|
type Entry = T;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn initial(&self) -> T {
|
fn initial(&self) -> T {
|
||||||
@ -434,6 +556,45 @@ where
|
|||||||
fn set_initial(&mut self, initial: T) {
|
fn set_initial(&mut self, initial: T) {
|
||||||
self.initial = initial;
|
self.initial = initial;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn usable_count(&self) -> usize {
|
||||||
|
*self.size.as_ref()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get(&self, idx: usize) -> &T {
|
||||||
|
&self.as_slice()[idx]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_mut(&mut self, idx: usize) -> &mut T {
|
||||||
|
&mut self.as_mut_slice()[idx]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn hash(&self) -> u64 {
|
||||||
|
hash_slice(self.as_slice())
|
||||||
|
}
|
||||||
|
fn to_vec(&self) -> Vec<T> {
|
||||||
|
self.as_slice().to_vec()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T> AsSlice<T> for VariableMapObserver<'a, T>
|
||||||
|
where
|
||||||
|
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn as_slice(&self) -> &[T] {
|
||||||
|
self.map.as_slice()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<'a, T> AsMutSlice<T> for VariableMapObserver<'a, T>
|
||||||
|
where
|
||||||
|
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn as_mut_slice(&mut self) -> &mut [T] {
|
||||||
|
self.map.as_mut_slice()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> VariableMapObserver<'a, T>
|
impl<'a, T> VariableMapObserver<'a, T>
|
||||||
@ -498,7 +659,7 @@ static COUNT_CLASS_LOOKUP: [u8; 256] = [
|
|||||||
|
|
||||||
impl<I, S, M> Observer<I, S> for HitcountsMapObserver<M>
|
impl<I, S, M> Observer<I, S> for HitcountsMapObserver<M>
|
||||||
where
|
where
|
||||||
M: MapObserver<u8> + Observer<I, S>,
|
M: MapObserver<Entry = u8> + Observer<I, S>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn pre_exec(&mut self, state: &mut S, input: &I) -> Result<(), Error> {
|
fn pre_exec(&mut self, state: &mut S, input: &I) -> Result<(), Error> {
|
||||||
@ -527,7 +688,7 @@ where
|
|||||||
|
|
||||||
impl<M> HasLen for HitcountsMapObserver<M>
|
impl<M> HasLen for HitcountsMapObserver<M>
|
||||||
where
|
where
|
||||||
M: MapObserver<u8>,
|
M: MapObserver,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn len(&self) -> usize {
|
fn len(&self) -> usize {
|
||||||
@ -535,24 +696,11 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M> MapObserver<u8> for HitcountsMapObserver<M>
|
impl<M> MapObserver for HitcountsMapObserver<M>
|
||||||
where
|
where
|
||||||
M: MapObserver<u8>,
|
M: MapObserver<Entry = u8>,
|
||||||
{
|
{
|
||||||
#[inline]
|
type Entry = u8;
|
||||||
fn map(&self) -> Option<&[u8]> {
|
|
||||||
self.base.map()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn map_mut(&mut self) -> Option<&mut [u8]> {
|
|
||||||
self.base.map_mut()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn usable_count(&self) -> usize {
|
|
||||||
self.base.usable_count()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn initial(&self) -> u8 {
|
fn initial(&self) -> u8 {
|
||||||
@ -568,6 +716,47 @@ where
|
|||||||
fn set_initial(&mut self, initial: u8) {
|
fn set_initial(&mut self, initial: u8) {
|
||||||
self.base.set_initial(initial);
|
self.base.set_initial(initial);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn usable_count(&self) -> usize {
|
||||||
|
self.base.usable_count()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn get(&self, idx: usize) -> &u8 {
|
||||||
|
self.base.get(idx)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn get_mut(&mut self, idx: usize) -> &mut u8 {
|
||||||
|
self.base.get_mut(idx)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn hash(&self) -> u64 {
|
||||||
|
self.base.hash()
|
||||||
|
}
|
||||||
|
fn to_vec(&self) -> Vec<u8> {
|
||||||
|
self.base.to_vec()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<M> AsSlice<u8> for HitcountsMapObserver<M>
|
||||||
|
where
|
||||||
|
M: MapObserver + AsSlice<u8>,
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn as_slice(&self) -> &[u8] {
|
||||||
|
self.base.as_slice()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<M> AsMutSlice<u8> for HitcountsMapObserver<M>
|
||||||
|
where
|
||||||
|
M: MapObserver + AsMutSlice<u8>,
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn as_mut_slice(&mut self) -> &mut [u8] {
|
||||||
|
self.base.as_mut_slice()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M> HitcountsMapObserver<M>
|
impl<M> HitcountsMapObserver<M>
|
||||||
@ -586,19 +775,20 @@ where
|
|||||||
#[allow(clippy::unsafe_derive_deserialize)]
|
#[allow(clippy::unsafe_derive_deserialize)]
|
||||||
pub struct MultiMapObserver<'a, T>
|
pub struct MultiMapObserver<'a, T>
|
||||||
where
|
where
|
||||||
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned,
|
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||||
{
|
{
|
||||||
maps: Vec<OwnedSliceMut<'a, T>>,
|
maps: Vec<OwnedSliceMut<'a, T>>,
|
||||||
intervals: IntervalTree<usize, usize>,
|
intervals: IntervalTree<usize, usize>,
|
||||||
len: usize,
|
len: usize,
|
||||||
initial: T,
|
initial: T,
|
||||||
name: String,
|
name: String,
|
||||||
|
iter_idx: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, I, S, T> Observer<I, S> for MultiMapObserver<'a, T>
|
impl<'a, I, S, T> Observer<I, S> for MultiMapObserver<'a, T>
|
||||||
where
|
where
|
||||||
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||||
Self: MapObserver<T>,
|
Self: MapObserver,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn pre_exec(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> {
|
fn pre_exec(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> {
|
||||||
@ -608,7 +798,7 @@ where
|
|||||||
|
|
||||||
impl<'a, T> Named for MultiMapObserver<'a, T>
|
impl<'a, T> Named for MultiMapObserver<'a, T>
|
||||||
where
|
where
|
||||||
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned,
|
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn name(&self) -> &str {
|
fn name(&self) -> &str {
|
||||||
@ -618,7 +808,7 @@ where
|
|||||||
|
|
||||||
impl<'a, T> HasLen for MultiMapObserver<'a, T>
|
impl<'a, T> HasLen for MultiMapObserver<'a, T>
|
||||||
where
|
where
|
||||||
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned,
|
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn len(&self) -> usize {
|
fn len(&self) -> usize {
|
||||||
@ -626,19 +816,11 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> MapObserver<T> for MultiMapObserver<'a, T>
|
impl<'a, T> MapObserver for MultiMapObserver<'a, T>
|
||||||
where
|
where
|
||||||
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||||
{
|
{
|
||||||
#[inline]
|
type Entry = T;
|
||||||
fn map(&self) -> Option<&[T]> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn map_mut(&mut self) -> Option<&mut [T]> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get(&self, idx: usize) -> &T {
|
fn get(&self, idx: usize) -> &T {
|
||||||
@ -706,11 +888,15 @@ where
|
|||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn usable_count(&self) -> usize {
|
||||||
|
self.len()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> MultiMapObserver<'a, T>
|
impl<'a, T> MultiMapObserver<'a, T>
|
||||||
where
|
where
|
||||||
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned,
|
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||||
{
|
{
|
||||||
/// Creates a new [`MultiMapObserver`]
|
/// Creates a new [`MultiMapObserver`]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
@ -739,6 +925,7 @@ where
|
|||||||
len: idx,
|
len: idx,
|
||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
initial,
|
initial,
|
||||||
|
iter_idx: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -769,6 +956,31 @@ where
|
|||||||
len: idx,
|
len: idx,
|
||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
initial,
|
initial,
|
||||||
|
iter_idx: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a, 'it, T> IntoIterator for &'it mut MultiMapObserver<'a, T>
|
||||||
|
where
|
||||||
|
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||||
|
{
|
||||||
|
type Item = <IterMut<'it, T> as Iterator>::Item;
|
||||||
|
type IntoIter = Flatten<IterMut<'it, OwnedSliceMut<'a, T>>>;
|
||||||
|
|
||||||
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
|
self.maps.iter_mut().flatten()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, 'it, T> IntoIterator for &'it MultiMapObserver<'a, T>
|
||||||
|
where
|
||||||
|
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
||||||
|
{
|
||||||
|
type Item = <Iter<'it, T> as Iterator>::Item;
|
||||||
|
type IntoIter = Flatten<Iter<'it, OwnedSliceMut<'a, T>>>;
|
||||||
|
|
||||||
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
|
self.maps.iter().flatten()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -19,34 +19,33 @@ use alloc::{
|
|||||||
vec::Vec,
|
vec::Vec,
|
||||||
};
|
};
|
||||||
use core::{fmt::Debug, marker::PhantomData, time::Duration};
|
use core::{fmt::Debug, marker::PhantomData, time::Duration};
|
||||||
use num_traits::PrimInt;
|
use num_traits::Bounded;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
/// The calibration stage will measure the average exec time and the target's stability for this input.
|
/// The calibration stage will measure the average exec time and the target's stability for this input.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct CalibrationStage<I, O, OT, S, T>
|
pub struct CalibrationStage<I, O, OT, S>
|
||||||
where
|
where
|
||||||
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
|
||||||
I: Input,
|
I: Input,
|
||||||
O: MapObserver<T>,
|
O: MapObserver,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
S: HasCorpus<I> + HasMetadata,
|
S: HasCorpus<I> + HasMetadata,
|
||||||
{
|
{
|
||||||
map_observer_name: String,
|
map_observer_name: String,
|
||||||
stage_max: usize,
|
stage_max: usize,
|
||||||
phantom: PhantomData<(I, O, OT, S, T)>,
|
phantom: PhantomData<(I, O, OT, S)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
const CAL_STAGE_START: usize = 4;
|
const CAL_STAGE_START: usize = 4;
|
||||||
const CAL_STAGE_MAX: usize = 16;
|
const CAL_STAGE_MAX: usize = 16;
|
||||||
|
|
||||||
impl<E, EM, I, O, OT, S, T, Z> Stage<E, EM, S, Z> for CalibrationStage<I, O, OT, S, T>
|
impl<E, EM, I, O, OT, S, Z> Stage<E, EM, S, Z> for CalibrationStage<I, O, OT, S>
|
||||||
where
|
where
|
||||||
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
|
||||||
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
|
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
|
||||||
EM: EventFirer<I>,
|
EM: EventFirer<I>,
|
||||||
I: Input,
|
I: Input,
|
||||||
O: MapObserver<T>,
|
O: MapObserver,
|
||||||
|
for<'de> <O as MapObserver>::Entry: Serialize + Deserialize<'de> + 'static,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
S: HasCorpus<I> + HasMetadata + HasFeedbackStates + HasClientPerfMonitor,
|
S: HasCorpus<I> + HasMetadata + HasFeedbackStates + HasClientPerfMonitor,
|
||||||
Z: Evaluator<E, EM, I, S>,
|
Z: Evaluator<E, EM, I, S>,
|
||||||
@ -94,8 +93,6 @@ where
|
|||||||
.observers()
|
.observers()
|
||||||
.match_name::<O>(&self.map_observer_name)
|
.match_name::<O>(&self.map_observer_name)
|
||||||
.ok_or_else(|| Error::KeyNotFound("MapObserver not found".to_string()))?
|
.ok_or_else(|| Error::KeyNotFound("MapObserver not found".to_string()))?
|
||||||
.map()
|
|
||||||
.unwrap()
|
|
||||||
.to_vec();
|
.to_vec();
|
||||||
|
|
||||||
// Run CAL_STAGE_START - 1 times, increase by 2 for every time a new
|
// Run CAL_STAGE_START - 1 times, increase by 2 for every time a new
|
||||||
@ -137,19 +134,17 @@ where
|
|||||||
.observers()
|
.observers()
|
||||||
.match_name::<O>(&self.map_observer_name)
|
.match_name::<O>(&self.map_observer_name)
|
||||||
.ok_or_else(|| Error::KeyNotFound("MapObserver not found".to_string()))?
|
.ok_or_else(|| Error::KeyNotFound("MapObserver not found".to_string()))?
|
||||||
.map()
|
|
||||||
.unwrap()
|
|
||||||
.to_vec();
|
.to_vec();
|
||||||
|
|
||||||
let history_map = &mut state
|
let history_map = &mut state
|
||||||
.feedback_states_mut()
|
.feedback_states_mut()
|
||||||
.match_name_mut::<MapFeedbackState<T>>(&self.map_observer_name)
|
.match_name_mut::<MapFeedbackState<O::Entry>>(&self.map_observer_name)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.history_map;
|
.history_map;
|
||||||
|
|
||||||
for j in 0..map_len {
|
for j in 0..map_len {
|
||||||
if map_first[j] != map[j] && history_map[j] != T::max_value() {
|
if map_first[j] != map[j] && history_map[j] != O::Entry::max_value() {
|
||||||
history_map[j] = T::max_value();
|
history_map[j] = O::Entry::max_value();
|
||||||
unstable_entries += 1;
|
unstable_entries += 1;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -306,11 +301,10 @@ impl PowerScheduleMetadata {
|
|||||||
|
|
||||||
crate::impl_serdeany!(PowerScheduleMetadata);
|
crate::impl_serdeany!(PowerScheduleMetadata);
|
||||||
|
|
||||||
impl<I, O, OT, S, T> CalibrationStage<I, O, OT, S, T>
|
impl<I, O, OT, S> CalibrationStage<I, O, OT, S>
|
||||||
where
|
where
|
||||||
T: PrimInt + Default + Copy + 'static + Serialize + serde::de::DeserializeOwned + Debug,
|
|
||||||
I: Input,
|
I: Input,
|
||||||
O: MapObserver<T>,
|
O: MapObserver,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
S: HasCorpus<I> + HasMetadata,
|
S: HasCorpus<I> + HasMetadata,
|
||||||
{
|
{
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
use alloc::string::{String, ToString};
|
use alloc::string::{String, ToString};
|
||||||
use core::{fmt::Debug, marker::PhantomData};
|
use core::{fmt::Debug, marker::PhantomData};
|
||||||
use num_traits::PrimInt;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
corpus::{Corpus, IsFavoredMetadata, PowerScheduleTestcaseMetaData, Testcase},
|
corpus::{Corpus, IsFavoredMetadata, PowerScheduleTestcaseMetaData, Testcase},
|
||||||
@ -34,13 +33,12 @@ const HAVOC_MAX_MULT: f64 = 64.0;
|
|||||||
|
|
||||||
/// The mutational stage using power schedules
|
/// The mutational stage using power schedules
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct PowerMutationalStage<E, EM, I, M, O, OT, S, T, Z>
|
pub struct PowerMutationalStage<E, EM, I, M, O, OT, S, Z>
|
||||||
where
|
where
|
||||||
T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned + Debug,
|
|
||||||
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
|
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
|
||||||
I: Input,
|
I: Input,
|
||||||
M: Mutator<I, S>,
|
M: Mutator<I, S>,
|
||||||
O: MapObserver<T>,
|
O: MapObserver,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
S: HasClientPerfMonitor + HasCorpus<I> + HasMetadata,
|
S: HasClientPerfMonitor + HasCorpus<I> + HasMetadata,
|
||||||
Z: Evaluator<E, EM, I, S>,
|
Z: Evaluator<E, EM, I, S>,
|
||||||
@ -50,17 +48,16 @@ where
|
|||||||
/// The employed power schedule strategy
|
/// The employed power schedule strategy
|
||||||
strat: PowerSchedule,
|
strat: PowerSchedule,
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
phantom: PhantomData<(E, EM, I, O, OT, S, T, Z)>,
|
phantom: PhantomData<(E, EM, I, O, OT, S, Z)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E, EM, I, M, O, OT, S, T, Z> MutationalStage<E, EM, I, M, S, Z>
|
impl<E, EM, I, M, O, OT, S, Z> MutationalStage<E, EM, I, M, S, Z>
|
||||||
for PowerMutationalStage<E, EM, I, M, O, OT, S, T, Z>
|
for PowerMutationalStage<E, EM, I, M, O, OT, S, Z>
|
||||||
where
|
where
|
||||||
T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned + Debug,
|
|
||||||
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
|
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
|
||||||
I: Input,
|
I: Input,
|
||||||
M: Mutator<I, S>,
|
M: Mutator<I, S>,
|
||||||
O: MapObserver<T>,
|
O: MapObserver,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
S: HasClientPerfMonitor + HasCorpus<I> + HasMetadata,
|
S: HasClientPerfMonitor + HasCorpus<I> + HasMetadata,
|
||||||
Z: Evaluator<E, EM, I, S>,
|
Z: Evaluator<E, EM, I, S>,
|
||||||
@ -153,14 +150,12 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E, EM, I, M, O, OT, S, T, Z> Stage<E, EM, S, Z>
|
impl<E, EM, I, M, O, OT, S, Z> Stage<E, EM, S, Z> for PowerMutationalStage<E, EM, I, M, O, OT, S, Z>
|
||||||
for PowerMutationalStage<E, EM, I, M, O, OT, S, T, Z>
|
|
||||||
where
|
where
|
||||||
T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned + Debug,
|
|
||||||
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
|
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
|
||||||
I: Input,
|
I: Input,
|
||||||
M: Mutator<I, S>,
|
M: Mutator<I, S>,
|
||||||
O: MapObserver<T>,
|
O: MapObserver,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
S: HasClientPerfMonitor + HasCorpus<I> + HasMetadata,
|
S: HasClientPerfMonitor + HasCorpus<I> + HasMetadata,
|
||||||
Z: Evaluator<E, EM, I, S>,
|
Z: Evaluator<E, EM, I, S>,
|
||||||
@ -180,13 +175,12 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E, EM, I, M, O, OT, S, T, Z> PowerMutationalStage<E, EM, I, M, O, OT, S, T, Z>
|
impl<E, EM, I, M, O, OT, S, Z> PowerMutationalStage<E, EM, I, M, O, OT, S, Z>
|
||||||
where
|
where
|
||||||
T: PrimInt + Default + Copy + 'static + serde::Serialize + serde::de::DeserializeOwned + Debug,
|
|
||||||
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
|
E: Executor<EM, I, S, Z> + HasObservers<I, OT, S>,
|
||||||
I: Input,
|
I: Input,
|
||||||
M: Mutator<I, S>,
|
M: Mutator<I, S>,
|
||||||
O: MapObserver<T>,
|
O: MapObserver,
|
||||||
OT: ObserversTuple<I, S>,
|
OT: ObserversTuple<I, S>,
|
||||||
S: HasClientPerfMonitor + HasCorpus<I> + HasMetadata,
|
S: HasClientPerfMonitor + HasCorpus<I> + HasMetadata,
|
||||||
Z: Evaluator<E, EM, I, S>,
|
Z: Evaluator<E, EM, I, S>,
|
||||||
|
@ -13,7 +13,10 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use libafl::{
|
use libafl::{
|
||||||
bolts::shmem::{ShMem, ShMemProvider, StdShMemProvider},
|
bolts::{
|
||||||
|
shmem::{ShMem, ShMemProvider, StdShMemProvider},
|
||||||
|
AsSlice,
|
||||||
|
},
|
||||||
observers::concolic::{
|
observers::concolic::{
|
||||||
serialization_format::{MessageFileReader, MessageFileWriter, DEFAULT_ENV_NAME},
|
serialization_format::{MessageFileReader, MessageFileWriter, DEFAULT_ENV_NAME},
|
||||||
EXPRESSION_PRUNING, HITMAP_ENV_NAME, NO_FLOAT_ENV_NAME, SELECTIVE_SYMBOLICATION_ENV_NAME,
|
EXPRESSION_PRUNING, HITMAP_ENV_NAME, NO_FLOAT_ENV_NAME, SELECTIVE_SYMBOLICATION_ENV_NAME,
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
//! Generates `DrCov` traces
|
//! Generates `DrCov` traces
|
||||||
use ahash::AHasher;
|
use ahash::AHasher;
|
||||||
use libafl::{
|
use libafl::{
|
||||||
|
bolts::AsSlice,
|
||||||
inputs::{HasTargetBytes, Input},
|
inputs::{HasTargetBytes, Input},
|
||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
use libafl::inputs::{HasTargetBytes, Input};
|
use libafl::{
|
||||||
use libafl::Error;
|
bolts::AsSlice,
|
||||||
|
inputs::{HasTargetBytes, Input},
|
||||||
|
Error,
|
||||||
|
};
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
use libafl_targets::drcov::DrCovBasicBlock;
|
use libafl_targets::drcov::DrCovBasicBlock;
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ use libafl::{
|
|||||||
rands::StdRand,
|
rands::StdRand,
|
||||||
shmem::{ShMem, ShMemProvider, StdShMemProvider},
|
shmem::{ShMem, ShMemProvider, StdShMemProvider},
|
||||||
tuples::{tuple_list, Merge},
|
tuples::{tuple_list, Merge},
|
||||||
|
AsMutSlice,
|
||||||
},
|
},
|
||||||
corpus::{
|
corpus::{
|
||||||
CachedOnDiskCorpus, Corpus, IndexesLenTimeMinimizerCorpusScheduler, OnDiskCorpus,
|
CachedOnDiskCorpus, Corpus, IndexesLenTimeMinimizerCorpusScheduler, OnDiskCorpus,
|
||||||
|
@ -13,6 +13,7 @@ use libafl::{
|
|||||||
rands::StdRand,
|
rands::StdRand,
|
||||||
shmem::{ShMemProvider, StdShMemProvider},
|
shmem::{ShMemProvider, StdShMemProvider},
|
||||||
tuples::{tuple_list, Merge},
|
tuples::{tuple_list, Merge},
|
||||||
|
AsSlice,
|
||||||
},
|
},
|
||||||
corpus::{
|
corpus::{
|
||||||
CachedOnDiskCorpus, Corpus, IndexesLenTimeMinimizerCorpusScheduler, OnDiskCorpus,
|
CachedOnDiskCorpus, Corpus, IndexesLenTimeMinimizerCorpusScheduler, OnDiskCorpus,
|
||||||
|
@ -12,6 +12,7 @@ use libafl::{
|
|||||||
rands::StdRand,
|
rands::StdRand,
|
||||||
shmem::{ShMemProvider, StdShMemProvider},
|
shmem::{ShMemProvider, StdShMemProvider},
|
||||||
tuples::{tuple_list, Merge},
|
tuples::{tuple_list, Merge},
|
||||||
|
AsSlice,
|
||||||
},
|
},
|
||||||
corpus::{
|
corpus::{
|
||||||
CachedOnDiskCorpus, Corpus, IndexesLenTimeMinimizerCorpusScheduler, OnDiskCorpus,
|
CachedOnDiskCorpus, Corpus, IndexesLenTimeMinimizerCorpusScheduler, OnDiskCorpus,
|
||||||
|
@ -187,11 +187,11 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn map(&self) -> &CmpLogMap {
|
fn cmp_map(&self) -> &CmpLogMap {
|
||||||
self.map.as_ref()
|
self.map.as_ref()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn map_mut(&mut self) -> &mut CmpLogMap {
|
fn cmp_map_mut(&mut self) -> &mut CmpLogMap {
|
||||||
self.map.as_mut()
|
self.map.as_mut()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user