Add bolts::math, make functions const, cleanup (#1444)
* Make some functions const * fix isprint * more const * move integer_sqrt to bolts, use binary search, use u128 to handle extreme values * Technically correct * clippy * u64 algo * More test * cumulative_distribution to in_place * move calculate_cumulative_distribution_in_place to bolts * clippy * Move math stuff to bolts::math * actually add math * math? * For some reason this fixes things, dunno * fix builds? * does that help? * clippy ignores * more clean clippy * more cfg_attr
This commit is contained in:
parent
d338b30c08
commit
454142c29e
@ -326,6 +326,10 @@ where
|
||||
|
||||
/// The Metadata for each testcase used in power schedules.
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
#[cfg_attr(
|
||||
any(not(feature = "serdeany_autoreg"), miri),
|
||||
allow(clippy::unsafe_derive_deserialize)
|
||||
)] // for SerdeAny
|
||||
pub struct SchedulerTestcaseMetadata {
|
||||
/// Number of bits set in bitmap, updated in calibrate_case
|
||||
bitmap_size: u64,
|
||||
|
@ -47,6 +47,10 @@ use crate::{
|
||||
|
||||
/// How an execution finished.
|
||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[cfg_attr(
|
||||
any(not(feature = "serdeany_autoreg"), miri),
|
||||
allow(clippy::unsafe_derive_deserialize)
|
||||
)] // for SerdeAny
|
||||
pub enum ExitKind {
|
||||
/// The run exited normally.
|
||||
Ok,
|
||||
@ -69,6 +73,10 @@ pub enum ExitKind {
|
||||
|
||||
/// How one of the diffing executions finished.
|
||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[cfg_attr(
|
||||
any(not(feature = "serdeany_autoreg"), miri),
|
||||
allow(clippy::unsafe_derive_deserialize)
|
||||
)] // for SerdeAny
|
||||
pub enum DiffExitKind {
|
||||
/// The run exited normally.
|
||||
Ok,
|
||||
|
@ -222,6 +222,10 @@ where
|
||||
|
||||
/// A testcase metadata holding a list of indexes of a map
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[cfg_attr(
|
||||
any(not(feature = "serdeany_autoreg"), miri),
|
||||
allow(clippy::unsafe_derive_deserialize)
|
||||
)] // for SerdeAny
|
||||
pub struct MapIndexesMetadata {
|
||||
/// The list of indexes.
|
||||
pub list: Vec<usize>,
|
||||
@ -266,6 +270,10 @@ impl MapIndexesMetadata {
|
||||
|
||||
/// A testcase metadata holding a list of indexes of a map
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[cfg_attr(
|
||||
any(not(feature = "serdeany_autoreg"), miri),
|
||||
allow(clippy::unsafe_derive_deserialize)
|
||||
)] // for SerdeAny
|
||||
pub struct MapNoveltiesMetadata {
|
||||
/// A `list` of novelties.
|
||||
pub list: Vec<usize>,
|
||||
@ -300,6 +308,10 @@ impl MapNoveltiesMetadata {
|
||||
/// The state of [`MapFeedback`]
|
||||
#[derive(Default, Serialize, Deserialize, Clone, Debug)]
|
||||
#[serde(bound = "T: DeserializeOwned")]
|
||||
#[cfg_attr(
|
||||
any(not(feature = "serdeany_autoreg"), miri),
|
||||
allow(clippy::unsafe_derive_deserialize)
|
||||
)] // for SerdeAny
|
||||
pub struct MapFeedbackMetadata<T>
|
||||
where
|
||||
T: Default + Copy + 'static + Serialize,
|
||||
|
@ -109,7 +109,7 @@ impl From<BytesInput> for Vec<u8> {
|
||||
impl BytesInput {
|
||||
/// Creates a new bytes input using the given bytes
|
||||
#[must_use]
|
||||
pub fn new(bytes: Vec<u8>) -> Self {
|
||||
pub const fn new(bytes: Vec<u8>) -> Self {
|
||||
Self { bytes }
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,10 @@ pub enum GeneralizedItem {
|
||||
|
||||
/// Metadata regarding the generalised content of an input
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(
|
||||
any(not(feature = "serdeany_autoreg"), miri),
|
||||
allow(clippy::unsafe_derive_deserialize)
|
||||
)] // for SerdeAny
|
||||
pub struct GeneralizedInputMetadata {
|
||||
generalized: Vec<GeneralizedItem>,
|
||||
}
|
||||
|
@ -72,6 +72,10 @@ where
|
||||
|
||||
/// The metadata used for `gramatron`
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[cfg_attr(
|
||||
any(not(feature = "serdeany_autoreg"), miri),
|
||||
allow(clippy::unsafe_derive_deserialize)
|
||||
)] // for SerdeAny
|
||||
pub struct GramatronIdxMapMetadata {
|
||||
/// The map containing a vec for each terminal
|
||||
pub map: HashMap<usize, Vec<usize>>,
|
||||
|
@ -28,6 +28,10 @@ use crate::{
|
||||
/// On the other hand, in the core fuzzing mode, the fuzzer chooses the best `swarms`, which was determined during the pilot fuzzing mode, to compute the probability to choose the operation operator.
|
||||
/// With the current implementation we are always in the pacemaker fuzzing mode.
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
#[cfg_attr(
|
||||
any(not(feature = "serdeany_autoreg"), miri),
|
||||
allow(clippy::unsafe_derive_deserialize)
|
||||
)] // for SerdeAny
|
||||
pub struct MOpt {
|
||||
/// Random number generator
|
||||
pub rand: StdRand,
|
||||
|
@ -24,6 +24,10 @@ use crate::{
|
||||
|
||||
/// The metadata placed in a [`crate::corpus::Testcase`] by a [`LoggerScheduledMutator`].
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[cfg_attr(
|
||||
any(not(feature = "serdeany_autoreg"), miri),
|
||||
allow(clippy::unsafe_derive_deserialize)
|
||||
)] // for SerdeAny
|
||||
pub struct LogMutationMetadata {
|
||||
/// A list of logs
|
||||
pub list: Vec<String>,
|
||||
|
@ -34,8 +34,8 @@ use crate::{
|
||||
};
|
||||
|
||||
/// A state metadata holding a list of tokens
|
||||
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
|
||||
#[allow(clippy::unsafe_derive_deserialize)]
|
||||
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
|
||||
pub struct Tokens {
|
||||
// We keep a vec and a set, set for faster deduplication, vec for access
|
||||
tokens_vec: Vec<Vec<u8>>,
|
||||
@ -1759,18 +1759,22 @@ impl TextType {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if the given `u8` char is
|
||||
/// in the valid ascii range (`<= 0x7F`)
|
||||
#[inline]
|
||||
fn isascii(c: u8) -> bool {
|
||||
const fn isascii(c: u8) -> bool {
|
||||
c <= 0x7F
|
||||
}
|
||||
|
||||
/// Returns `true` if the given `u8` char is
|
||||
/// a valid printable character (between `0x20` and `0x7E`)
|
||||
#[inline]
|
||||
fn isprint(c: u8) -> bool {
|
||||
(0x20..=0x7e).contains(&c)
|
||||
const fn isprint(c: u8) -> bool {
|
||||
c >= 0x20 && c <= 0x7E
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn strlen(buf: &[u8]) -> usize {
|
||||
const fn strlen(buf: &[u8]) -> usize {
|
||||
let mut count = 0;
|
||||
while count < buf.len() {
|
||||
if buf[count] == 0x0 {
|
||||
|
@ -8,7 +8,9 @@ use core::{
|
||||
marker::PhantomData,
|
||||
};
|
||||
|
||||
use libafl_bolts::{calculate_cumulative_sum_in_place, impl_serdeany, rands::Rand, Named};
|
||||
use libafl_bolts::{
|
||||
impl_serdeany, math::calculate_cumulative_distribution_in_place, rands::Rand, Named,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
pub use crate::mutators::{mutations::*, token_mutations::*};
|
||||
@ -22,6 +24,10 @@ use crate::{
|
||||
|
||||
/// Metadata in the state, that controls the behavior of the [`TuneableScheduledMutator`] at runtime
|
||||
#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
|
||||
#[cfg_attr(
|
||||
any(not(feature = "serdeany_autoreg"), miri),
|
||||
allow(clippy::unsafe_derive_deserialize)
|
||||
)] // for SerdeAny
|
||||
pub struct TuneableScheduledMutatorMetadata {
|
||||
/// The offsets of mutators to run, in order. Clear to fall back to random,
|
||||
/// or use `mutation_probabilities`
|
||||
@ -40,6 +46,8 @@ pub struct TuneableScheduledMutatorMetadata {
|
||||
pub iter_probabilities_pow_cumulative: Vec<f32>,
|
||||
}
|
||||
|
||||
impl_serdeany!(TuneableScheduledMutatorMetadata);
|
||||
|
||||
impl Default for TuneableScheduledMutatorMetadata {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
@ -70,8 +78,6 @@ impl TuneableScheduledMutatorMetadata {
|
||||
}
|
||||
}
|
||||
|
||||
impl_serdeany!(TuneableScheduledMutatorMetadata);
|
||||
|
||||
/// A [`Mutator`] that schedules one of the embedded mutations on each call.
|
||||
/// The index of the next mutation can be set.
|
||||
pub struct TuneableScheduledMutator<I, MT, S>
|
||||
@ -247,36 +253,6 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the cumulative distribution function for a discrete distribution.
|
||||
fn calculate_cumulative_distribution(probabilities: Vec<f32>) -> Result<Vec<f32>, Error> {
|
||||
if probabilities.is_empty() {
|
||||
return Err(Error::illegal_argument("empty list of probabilities"));
|
||||
}
|
||||
|
||||
if !probabilities.iter().all(|&p| (0.0..=1.0).contains(&p)) {
|
||||
return Err(Error::illegal_argument(format!(
|
||||
"invalid probability distribution: {probabilities:?}"
|
||||
)));
|
||||
}
|
||||
|
||||
let mut cumulative = probabilities;
|
||||
calculate_cumulative_sum_in_place(&mut cumulative);
|
||||
|
||||
// The cumulative sum should be roughly equal to 1.
|
||||
let last = cumulative.last_mut().unwrap();
|
||||
if num_traits::abs(*last - 1.0_f32) > 1.0e-4 {
|
||||
return Err(Error::illegal_argument(format!(
|
||||
"sum of probabilities ({}) is not 1",
|
||||
*last
|
||||
)));
|
||||
}
|
||||
|
||||
// Clamp the end of the vector to account for floating point errors.
|
||||
*last = 1.0_f32;
|
||||
|
||||
Ok(cumulative)
|
||||
}
|
||||
|
||||
impl<S> TuneableScheduledMutator<(), (), S>
|
||||
where
|
||||
S: HasRand + HasMetadata,
|
||||
@ -317,7 +293,7 @@ where
|
||||
/// Setting this function will unset everything previously set in `set_iters`.
|
||||
pub fn set_iter_probabilities_pow(
|
||||
state: &mut S,
|
||||
iter_probabilities_pow: Vec<f32>,
|
||||
mut iter_probabilities_pow: Vec<f32>,
|
||||
) -> Result<(), Error> {
|
||||
if iter_probabilities_pow.len() >= 32 {
|
||||
return Err(Error::illegal_argument(
|
||||
@ -328,8 +304,8 @@ where
|
||||
metadata.iters = None;
|
||||
|
||||
// we precalculate the cumulative probability to be faster when sampling later.
|
||||
metadata.iter_probabilities_pow_cumulative =
|
||||
calculate_cumulative_distribution(iter_probabilities_pow)?;
|
||||
calculate_cumulative_distribution_in_place(&mut iter_probabilities_pow)?;
|
||||
metadata.iter_probabilities_pow_cumulative = iter_probabilities_pow;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -353,15 +329,15 @@ where
|
||||
/// Setting the probabilities will remove the value set through `set_mutation_ids`.
|
||||
pub fn set_mutation_probabilities(
|
||||
state: &mut S,
|
||||
mutation_probabilities: Vec<f32>,
|
||||
mut mutation_probabilities: Vec<f32>,
|
||||
) -> Result<(), Error> {
|
||||
let metadata = TuneableScheduledMutatorMetadata::get_mut(state).unwrap();
|
||||
metadata.mutation_ids.clear();
|
||||
metadata.next_id = 0.into();
|
||||
|
||||
// we precalculate the cumulative probability to be faster when sampling later.
|
||||
metadata.mutation_probabilities_cumulative =
|
||||
calculate_cumulative_distribution(mutation_probabilities)?;
|
||||
calculate_cumulative_distribution_in_place(&mut mutation_probabilities)?;
|
||||
metadata.mutation_probabilities_cumulative = mutation_probabilities;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -395,8 +371,7 @@ mod test {
|
||||
use libafl_bolts::tuples::tuple_list;
|
||||
|
||||
use super::{
|
||||
calculate_cumulative_distribution, BitFlipMutator, ByteDecMutator,
|
||||
TuneableScheduledMutator, TuneableScheduledMutatorMetadata,
|
||||
BitFlipMutator, ByteDecMutator, TuneableScheduledMutator, TuneableScheduledMutatorMetadata,
|
||||
};
|
||||
use crate::{
|
||||
inputs::BytesInput,
|
||||
@ -406,6 +381,11 @@ mod test {
|
||||
|
||||
#[test]
|
||||
fn test_tuning() {
|
||||
#[cfg(any(not(feature = "serdeany_autoreg"), miri))]
|
||||
unsafe {
|
||||
TuneableScheduledMutatorMetadata::register();
|
||||
}
|
||||
|
||||
let mut state: NopState<BytesInput> = NopState::new();
|
||||
let mutators = tuple_list!(
|
||||
BitFlipMutator::new(),
|
||||
@ -423,28 +403,12 @@ mod test {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_cdf_fails_with_invalid_probs() {
|
||||
// Distribution has to sum up to 1.
|
||||
assert!(calculate_cumulative_distribution(vec![]).is_err());
|
||||
assert!(calculate_cumulative_distribution(vec![0.0]).is_err());
|
||||
assert!(calculate_cumulative_distribution(vec![0.9]).is_err());
|
||||
assert!(calculate_cumulative_distribution(vec![0.9, 0.9]).is_err());
|
||||
assert!(calculate_cumulative_distribution(vec![f32::NAN]).is_err());
|
||||
assert!(calculate_cumulative_distribution(vec![f32::INFINITY]).is_err());
|
||||
assert!(calculate_cumulative_distribution(vec![f32::NEG_INFINITY]).is_err());
|
||||
|
||||
// Elements have to be between 0 and 1
|
||||
assert!(calculate_cumulative_distribution(vec![-0.5, 0.5, 0.5]).is_err());
|
||||
|
||||
assert!(calculate_cumulative_distribution(vec![1.0]).is_ok());
|
||||
assert!(calculate_cumulative_distribution(vec![0.0, 1.0]).is_ok());
|
||||
assert!(calculate_cumulative_distribution(vec![0.0, 1.0, 0.0]).is_ok());
|
||||
assert!(calculate_cumulative_distribution(vec![0.5, 0.5]).is_ok());
|
||||
assert!(calculate_cumulative_distribution(vec![0.2; 5]).is_ok());
|
||||
fn test_mutation_distribution() {
|
||||
#[cfg(any(not(feature = "serdeany_autoreg"), miri))]
|
||||
unsafe {
|
||||
TuneableScheduledMutatorMetadata::register();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mutation_distribution() {
|
||||
let mut state: NopState<BytesInput> = NopState::new();
|
||||
let mutators = tuple_list!(
|
||||
BitFlipMutator::new(),
|
||||
|
@ -55,6 +55,10 @@ impl CmpValues {
|
||||
|
||||
/// A state metadata holding a list of values logged from comparisons
|
||||
#[derive(Debug, Default, Serialize, Deserialize)]
|
||||
#[cfg_attr(
|
||||
any(not(feature = "serdeany_autoreg"), miri),
|
||||
allow(clippy::unsafe_derive_deserialize)
|
||||
)] // for SerdeAny
|
||||
pub struct CmpValuesMetadata {
|
||||
/// A `list` of values.
|
||||
#[serde(skip)]
|
||||
@ -562,6 +566,10 @@ where
|
||||
|
||||
/// A state metadata holding a list of values logged from comparisons. AFL++ RQ version.
|
||||
#[derive(Debug, Default, Serialize, Deserialize)]
|
||||
#[cfg_attr(
|
||||
any(not(feature = "serdeany_autoreg"), miri),
|
||||
allow(clippy::unsafe_derive_deserialize)
|
||||
)] // for SerdeAny
|
||||
pub struct AFLppCmpValuesMetadata {
|
||||
/// The first map of AFLppCmpVals retrieved by running the un-mutated input
|
||||
#[serde(skip)]
|
||||
|
@ -22,6 +22,10 @@ use crate::{
|
||||
|
||||
/// A testcase metadata holding a list of indexes of a map
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[cfg_attr(
|
||||
any(not(feature = "serdeany_autoreg"), miri),
|
||||
allow(clippy::unsafe_derive_deserialize)
|
||||
)] // for SerdeAny
|
||||
pub struct AccountingIndexesMetadata {
|
||||
/// The list of indexes.
|
||||
pub list: Vec<usize>,
|
||||
@ -73,6 +77,10 @@ impl AccountingIndexesMetadata {
|
||||
|
||||
/// A state metadata holding a map of favoreds testcases for each map entry
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[cfg_attr(
|
||||
any(not(feature = "serdeany_autoreg"), miri),
|
||||
allow(clippy::unsafe_derive_deserialize)
|
||||
)] // for SerdeAny
|
||||
pub struct TopAccountingMetadata {
|
||||
/// map index -> corpus index
|
||||
pub map: HashMap<usize, CorpusId>,
|
||||
|
@ -3,6 +3,7 @@
|
||||
use alloc::string::{String, ToString};
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use libafl_bolts::math::integer_sqrt;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
@ -14,16 +15,6 @@ use crate::{
|
||||
Error,
|
||||
};
|
||||
|
||||
fn integer_sqrt(val: u64) -> u64 {
|
||||
let mut i = 0;
|
||||
let mut r = 0;
|
||||
while r <= val {
|
||||
r = i * i;
|
||||
i += 1;
|
||||
}
|
||||
i - 1
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Copy, Default)]
|
||||
/// The state of the `EcoFuzz` scheduling algorithm
|
||||
pub enum EcoState {
|
||||
@ -38,6 +29,10 @@ pub enum EcoState {
|
||||
|
||||
/// The testcase Metadata for `EcoScheduler`
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, Default)]
|
||||
#[cfg_attr(
|
||||
any(not(feature = "serdeany_autoreg"), miri),
|
||||
allow(clippy::unsafe_derive_deserialize)
|
||||
)] // for SerdeAny
|
||||
pub struct EcoTestcaseMetadata {
|
||||
mutation_num: u64,
|
||||
exec_num: u64,
|
||||
@ -53,6 +48,10 @@ libafl_bolts::impl_serdeany!(EcoTestcaseMetadata);
|
||||
|
||||
/// The state Metadata for `EcoScheduler`
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, Default)]
|
||||
#[cfg_attr(
|
||||
any(not(feature = "serdeany_autoreg"), miri),
|
||||
allow(clippy::unsafe_derive_deserialize)
|
||||
)] // for SerdeAny
|
||||
pub struct EcoMetadata {
|
||||
state: EcoState,
|
||||
initial_corpus_count: Option<usize>,
|
||||
@ -283,7 +282,7 @@ where
|
||||
let tcmeta = tc.metadata_mut::<EcoTestcaseMetadata>()?;
|
||||
|
||||
tcmeta.exec_num = exec_num;
|
||||
tcmeta.serial = state.corpus().count() as u64 + 1;
|
||||
tcmeta.serial = (state.corpus().count() as u64).saturating_add(1);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -23,12 +23,20 @@ pub const DEFAULT_SKIP_NON_FAVORED_PROB: u64 = 95;
|
||||
|
||||
/// A testcase metadata saying if a testcase is favored
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[cfg_attr(
|
||||
any(not(feature = "serdeany_autoreg"), miri),
|
||||
allow(clippy::unsafe_derive_deserialize)
|
||||
)] // for SerdeAny
|
||||
pub struct IsFavoredMetadata {}
|
||||
|
||||
libafl_bolts::impl_serdeany!(IsFavoredMetadata);
|
||||
|
||||
/// A state metadata holding a map of favoreds testcases for each map entry
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[cfg_attr(
|
||||
any(not(feature = "serdeany_autoreg"), miri),
|
||||
allow(clippy::unsafe_derive_deserialize)
|
||||
)] // for SerdeAny
|
||||
pub struct TopRatedsMetadata {
|
||||
/// map index -> corpus index
|
||||
pub map: HashMap<usize, CorpusId>,
|
||||
|
@ -24,6 +24,10 @@ libafl_bolts::impl_serdeany!(SchedulerMetadata);
|
||||
|
||||
/// The metadata used for power schedules
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
#[cfg_attr(
|
||||
any(not(feature = "serdeany_autoreg"), miri),
|
||||
allow(clippy::unsafe_derive_deserialize)
|
||||
)] // for SerdeAny
|
||||
pub struct SchedulerMetadata {
|
||||
/// Powerschedule strategy
|
||||
strat: Option<PowerSchedule>,
|
||||
|
@ -27,6 +27,10 @@ where
|
||||
|
||||
/// A state metadata holding a map of probability of corpus elements.
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[cfg_attr(
|
||||
any(not(feature = "serdeany_autoreg"), miri),
|
||||
allow(clippy::unsafe_derive_deserialize)
|
||||
)] // for SerdeAny
|
||||
pub struct ProbabilityMetadata {
|
||||
/// corpus index -> probability
|
||||
pub map: HashMap<CorpusId, f64>,
|
||||
|
@ -18,6 +18,10 @@ use crate::{
|
||||
};
|
||||
|
||||
#[derive(Default, Clone, Copy, Eq, PartialEq, Debug, Serialize, Deserialize)]
|
||||
#[cfg_attr(
|
||||
any(not(feature = "serdeany_autoreg"), miri),
|
||||
allow(clippy::unsafe_derive_deserialize)
|
||||
)] // for SerdeAny
|
||||
struct TuneableSchedulerMetadata {
|
||||
next: Option<CorpusId>,
|
||||
}
|
||||
|
@ -24,9 +24,12 @@ use crate::{
|
||||
Error,
|
||||
};
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
|
||||
/// The Metadata for `WeightedScheduler`
|
||||
#[cfg_attr(
|
||||
any(not(feature = "serdeany_autoreg"), miri),
|
||||
allow(clippy::unsafe_derive_deserialize)
|
||||
)] // for SerdeAny
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct WeightedScheduleMetadata {
|
||||
/// The fuzzer execution spent in the current cycles
|
||||
runs_in_current_cycle: usize,
|
||||
|
@ -7,7 +7,7 @@ use alloc::{
|
||||
use core::{fmt::Debug, marker::PhantomData, time::Duration};
|
||||
|
||||
use hashbrown::HashSet;
|
||||
use libafl_bolts::{current_time, AsIter, Named};
|
||||
use libafl_bolts::{current_time, impl_serdeany, AsIter, Named};
|
||||
use num_traits::Bounded;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
@ -26,15 +26,19 @@ use crate::{
|
||||
Error,
|
||||
};
|
||||
|
||||
libafl_bolts::impl_serdeany!(UnstableEntriesMetadata);
|
||||
/// The metadata to keep unstable entries
|
||||
/// In libafl, the stability is the number of the unstable entries divided by the size of the map
|
||||
/// This is different from AFL++, which shows the number of the unstable entries divided by the number of filled entries.
|
||||
#[cfg_attr(
|
||||
any(not(feature = "serdeany_autoreg"), miri),
|
||||
allow(clippy::unsafe_derive_deserialize)
|
||||
)] // for SerdeAny
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct UnstableEntriesMetadata {
|
||||
unstable_entries: HashSet<usize>,
|
||||
map_len: usize,
|
||||
}
|
||||
impl_serdeany!(UnstableEntriesMetadata);
|
||||
|
||||
impl UnstableEntriesMetadata {
|
||||
#[must_use]
|
||||
|
@ -101,8 +101,12 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
/// Store the taint and the input
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[cfg_attr(
|
||||
any(not(feature = "serdeany_autoreg"), miri),
|
||||
allow(clippy::unsafe_derive_deserialize)
|
||||
)] // for SerdeAny
|
||||
pub struct TaintMetadata {
|
||||
input_vec: Vec<u8>,
|
||||
ranges: Vec<Range<usize>>,
|
||||
|
@ -16,6 +16,10 @@ use crate::{
|
||||
};
|
||||
|
||||
/// Metadata used to store information about disk dump indexes for names
|
||||
#[cfg_attr(
|
||||
any(not(feature = "serdeany_autoreg"), miri),
|
||||
allow(clippy::unsafe_derive_deserialize)
|
||||
)] // for SerdeAny
|
||||
#[derive(Default, Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct DumpToDiskMetadata {
|
||||
last_corpus: Option<CorpusId>,
|
||||
|
@ -25,7 +25,7 @@ use crate::{
|
||||
|
||||
const MAX_GENERALIZED_LEN: usize = 8192;
|
||||
|
||||
fn increment_by_offset(_list: &[Option<u8>], idx: usize, off: u8) -> usize {
|
||||
const fn increment_by_offset(_list: &[Option<u8>], idx: usize, off: u8) -> usize {
|
||||
idx + 1 + off as usize
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,10 @@ use crate::{
|
||||
};
|
||||
|
||||
/// Metadata used to store information about disk sync time
|
||||
#[cfg_attr(
|
||||
any(not(feature = "serdeany_autoreg"), miri),
|
||||
allow(clippy::unsafe_derive_deserialize)
|
||||
)] // for SerdeAny
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct SyncFromDiskMetadata {
|
||||
/// The last time the sync was done
|
||||
@ -191,6 +195,10 @@ where
|
||||
}
|
||||
|
||||
/// Metadata used to store information about the last sent testcase with `SyncFromBrokerStage`
|
||||
#[cfg_attr(
|
||||
any(not(feature = "serdeany_autoreg"), miri),
|
||||
allow(clippy::unsafe_derive_deserialize)
|
||||
)] // for SerdeAny
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct SyncFromBrokerMetadata {
|
||||
/// The `CorpusId` of the last sent testcase
|
||||
|
@ -20,6 +20,10 @@ use crate::{
|
||||
Error, Evaluator,
|
||||
};
|
||||
|
||||
#[cfg_attr(
|
||||
any(not(feature = "serdeany_autoreg"), miri),
|
||||
allow(clippy::unsafe_derive_deserialize)
|
||||
)] // for SerdeAny
|
||||
#[derive(Default, Clone, Copy, Eq, PartialEq, Debug, Serialize, Deserialize)]
|
||||
struct TuneableMutationalStageMetadata {
|
||||
iters: Option<u64>,
|
||||
|
@ -75,6 +75,21 @@ Welcome to `LibAFL`
|
||||
#![allow(clippy::borrow_as_ptr)]
|
||||
#![allow(clippy::borrow_deref_ref)]
|
||||
|
||||
/// We need some sort of "[`String`]" for errors in `no_alloc`...
|
||||
/// We can only support `'static` without allocator, so let's do that.
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
type String = &'static str;
|
||||
|
||||
/// We also need a non-allocating format...
|
||||
/// This one simply returns the `fmt` string.
|
||||
/// Good enough for simple errors, for anything else, use the `alloc` feature.
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
macro_rules! format {
|
||||
($fmt:literal) => {{
|
||||
$fmt
|
||||
}};
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
#[macro_use]
|
||||
extern crate std;
|
||||
@ -85,6 +100,55 @@ pub extern crate alloc;
|
||||
#[cfg(feature = "ctor")]
|
||||
#[doc(hidden)]
|
||||
pub use ctor::ctor;
|
||||
#[cfg(feature = "alloc")]
|
||||
pub mod anymap;
|
||||
#[cfg(feature = "std")]
|
||||
pub mod build_id;
|
||||
#[cfg(all(
|
||||
any(feature = "cli", feature = "frida_cli", feature = "qemu_cli"),
|
||||
feature = "std"
|
||||
))]
|
||||
pub mod cli;
|
||||
#[cfg(feature = "gzip")]
|
||||
pub mod compress;
|
||||
#[cfg(feature = "std")]
|
||||
pub mod core_affinity;
|
||||
pub mod cpu;
|
||||
#[cfg(feature = "std")]
|
||||
pub mod fs;
|
||||
#[cfg(feature = "alloc")]
|
||||
pub mod llmp;
|
||||
pub mod math;
|
||||
#[cfg(all(feature = "std", unix))]
|
||||
pub mod minibsod;
|
||||
pub mod os;
|
||||
#[cfg(feature = "alloc")]
|
||||
pub mod ownedref;
|
||||
pub mod rands;
|
||||
#[cfg(feature = "alloc")]
|
||||
pub mod serdeany;
|
||||
pub mod shmem;
|
||||
#[cfg(feature = "std")]
|
||||
pub mod staterestore;
|
||||
pub mod tuples;
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
use alloc::vec::Vec;
|
||||
use core::{iter::Iterator, time};
|
||||
#[cfg(feature = "std")]
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// The client ID == the sender id.
|
||||
#[repr(transparent)]
|
||||
#[derive(
|
||||
Debug, Default, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize,
|
||||
)]
|
||||
pub struct ClientId(pub u32);
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
use log::{Metadata, Record};
|
||||
|
||||
#[deprecated(
|
||||
since = "0.11.0",
|
||||
@ -112,21 +176,6 @@ use std::{env::VarError, io};
|
||||
#[cfg(feature = "libafl_derive")]
|
||||
pub use libafl_derive::SerdeAny;
|
||||
|
||||
/// We need some sort of "[`String`]" for errors in `no_alloc`...
|
||||
/// We can only support `'static` without allocator, so let's do that.
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
type String = &'static str;
|
||||
|
||||
/// We also need a non-allocating format...
|
||||
/// This one simply returns the `fmt` string.
|
||||
/// Good enough for simple errors, for anything else, use the `alloc` feature.
|
||||
#[cfg(not(feature = "alloc"))]
|
||||
macro_rules! format {
|
||||
($fmt:literal) => {{
|
||||
$fmt
|
||||
}};
|
||||
}
|
||||
|
||||
/// We need fixed names for many parts of this lib.
|
||||
pub trait Named {
|
||||
/// Provide the name of this element.
|
||||
@ -467,55 +516,6 @@ pub unsafe extern "C" fn external_current_millis() -> u64 {
|
||||
1000
|
||||
}
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
pub mod anymap;
|
||||
#[cfg(feature = "std")]
|
||||
pub mod build_id;
|
||||
#[cfg(all(
|
||||
any(feature = "cli", feature = "frida_cli", feature = "qemu_cli"),
|
||||
feature = "std"
|
||||
))]
|
||||
pub mod cli;
|
||||
#[cfg(feature = "gzip")]
|
||||
pub mod compress;
|
||||
#[cfg(feature = "std")]
|
||||
pub mod core_affinity;
|
||||
pub mod cpu;
|
||||
#[cfg(feature = "std")]
|
||||
pub mod fs;
|
||||
#[cfg(feature = "alloc")]
|
||||
pub mod llmp;
|
||||
#[cfg(all(feature = "std", unix))]
|
||||
pub mod minibsod;
|
||||
pub mod os;
|
||||
#[cfg(feature = "alloc")]
|
||||
pub mod ownedref;
|
||||
pub mod rands;
|
||||
#[cfg(feature = "alloc")]
|
||||
pub mod serdeany;
|
||||
pub mod shmem;
|
||||
#[cfg(feature = "std")]
|
||||
pub mod staterestore;
|
||||
pub mod tuples;
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
use alloc::vec::Vec;
|
||||
use core::{iter::Iterator, ops::AddAssign, time};
|
||||
#[cfg(feature = "std")]
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// The client ID == the sender id.
|
||||
#[repr(transparent)]
|
||||
#[derive(
|
||||
Debug, Default, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize,
|
||||
)]
|
||||
pub struct ClientId(pub u32);
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
use log::{Metadata, Record};
|
||||
|
||||
/// Can be converted to a slice
|
||||
pub trait AsSlice {
|
||||
/// Type of the entries in this slice
|
||||
@ -656,23 +656,6 @@ pub fn current_time() -> time::Duration {
|
||||
time::Duration::from_millis(millis)
|
||||
}
|
||||
|
||||
/// Given a u64 number, return a hashed number using this mixing function
|
||||
/// This function is used to hash an address into a more random number (used in `libafl_frida`).
|
||||
/// Mixing function: <http://mostlymangling.blogspot.com/2018/07/on-mixing-functions-in-fast-splittable.html>
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn xxh3_rrmxmx_mixer(v: u64) -> u64 {
|
||||
let tmp = (v >> 32) + ((v & 0xffffffff) << 32);
|
||||
let bitflip = 0x1cad21f72c81017c ^ 0xdb979082e96dd4de;
|
||||
let mut h64 = tmp ^ bitflip;
|
||||
h64 = h64.rotate_left(49) & h64.rotate_left(24);
|
||||
h64 = h64.wrapping_mul(0x9FB21C651E98DF25);
|
||||
h64 ^= (h64 >> 35) + 8;
|
||||
h64 = h64.wrapping_mul(0x9FB21C651E98DF25);
|
||||
h64 ^= h64 >> 28;
|
||||
h64
|
||||
}
|
||||
|
||||
/// Gets current nanoseconds since [`UNIX_EPOCH`]
|
||||
#[must_use]
|
||||
#[inline]
|
||||
@ -695,30 +678,6 @@ pub fn format_duration_hms(duration: &time::Duration) -> String {
|
||||
format!("{}h-{}m-{}s", (secs / 60) / 60, (secs / 60) % 60, secs % 60)
|
||||
}
|
||||
|
||||
/// Calculates the cumulative sum for a slice, in-place.
|
||||
/// The values are useful for example for cumulative probabilities.
|
||||
///
|
||||
/// So, to give an example:
|
||||
/// ```rust
|
||||
/// # extern crate libafl_bolts;
|
||||
/// use libafl_bolts::calculate_cumulative_sum_in_place;
|
||||
///
|
||||
/// let mut value = [2, 4, 1, 3];
|
||||
/// calculate_cumulative_sum_in_place(&mut value);
|
||||
/// assert_eq!(&[2, 6, 7, 10], &value);
|
||||
/// ```
|
||||
pub fn calculate_cumulative_sum_in_place<T>(mut_slice: &mut [T])
|
||||
where
|
||||
T: Default + AddAssign<T> + Copy,
|
||||
{
|
||||
let mut acc = T::default();
|
||||
|
||||
for val in mut_slice {
|
||||
acc += *val;
|
||||
*val = acc;
|
||||
}
|
||||
}
|
||||
|
||||
/// Stderr logger
|
||||
#[cfg(feature = "std")]
|
||||
pub static LIBAFL_STDERR_LOGGER: SimpleStderrLogger = SimpleStderrLogger::new();
|
||||
|
@ -521,6 +521,9 @@ fn next_shmem_size(max_alloc: usize) -> usize {
|
||||
|
||||
/// Initialize a new `llmp_page`. The size should be relative to
|
||||
/// `llmp_page->messages`
|
||||
///
|
||||
/// # Safety
|
||||
/// Will write to the raw SHM page header, should be safe for correct [`ShMem`] implementations
|
||||
unsafe fn llmp_page_init<SHM: ShMem>(shmem: &mut SHM, sender_id: ClientId, allow_reinit: bool) {
|
||||
#[cfg(feature = "llmp_debug")]
|
||||
log::trace!("llmp_page_init: shmem {:?}", &shmem);
|
||||
@ -551,6 +554,9 @@ unsafe fn llmp_page_init<SHM: ShMem>(shmem: &mut SHM, sender_id: ClientId, allow
|
||||
}
|
||||
|
||||
/// Get the next pointer and make sure it's in the current page, and has enough space.
|
||||
///
|
||||
/// # Safety
|
||||
/// Will dereference `last_msg`
|
||||
#[inline]
|
||||
unsafe fn llmp_next_msg_ptr_checked<SHM: ShMem>(
|
||||
map: &mut LlmpSharedMap<SHM>,
|
||||
@ -576,6 +582,9 @@ unsafe fn llmp_next_msg_ptr_checked<SHM: ShMem>(
|
||||
|
||||
/// Pointer to the message behind the last message
|
||||
/// The messages are padded, so accesses will be aligned properly.
|
||||
///
|
||||
/// # Safety
|
||||
/// Will dereference the `last_msg` ptr
|
||||
#[inline]
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
unsafe fn _llmp_next_msg_ptr(last_msg: *const LlmpMsg) -> *mut LlmpMsg {
|
||||
|
145
libafl_bolts/src/math.rs
Normal file
145
libafl_bolts/src/math.rs
Normal file
@ -0,0 +1,145 @@
|
||||
//! Math-related functions that we commonly (or at least sometimes) need
|
||||
|
||||
use core::ops::AddAssign;
|
||||
|
||||
use crate::Error;
|
||||
|
||||
/// Returns the cumulative distribution function for a discrete distribution.
|
||||
pub fn calculate_cumulative_distribution_in_place(probabilities: &mut [f32]) -> Result<(), Error> {
|
||||
if probabilities.is_empty() {
|
||||
return Err(Error::illegal_argument("empty list of probabilities"));
|
||||
}
|
||||
|
||||
if !probabilities.iter().all(|&p| (0.0..=1.0).contains(&p)) {
|
||||
return Err(Error::illegal_argument(format!(
|
||||
"invalid probability distribution: {probabilities:?}"
|
||||
)));
|
||||
}
|
||||
|
||||
let cumulative = probabilities;
|
||||
calculate_cumulative_sum_in_place(cumulative);
|
||||
|
||||
// The cumulative sum should be roughly equal to 1.
|
||||
let last = cumulative.last_mut().unwrap();
|
||||
let offset_to_1 = *last - 1.0_f32;
|
||||
if offset_to_1.is_nan() || offset_to_1 > 1.0e-4 || -offset_to_1 > 1.0e-4 {
|
||||
return Err(Error::illegal_argument(format!(
|
||||
"sum of probabilities ({last}) is not 1"
|
||||
)));
|
||||
}
|
||||
|
||||
// Clamp the end of the vector to account for floating point errors.
|
||||
*last = 1.0_f32;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Calculates the integer square root using binary search
|
||||
/// Algorithm from
|
||||
/// <https://en.wikipedia.org/wiki/Integer_square_root#Algorithm_using_binary_search>.
|
||||
#[must_use]
|
||||
pub const fn integer_sqrt(val: u64) -> u64 {
|
||||
if val == u64::MAX {
|
||||
return 2_u64.pow(32) - 1;
|
||||
}
|
||||
let mut ret = 0;
|
||||
let mut i = val + 1;
|
||||
let mut m;
|
||||
|
||||
while ret != i - 1 {
|
||||
m = (ret + i) / 2;
|
||||
|
||||
if m.saturating_mul(m) <= val {
|
||||
ret = m;
|
||||
} else {
|
||||
i = m;
|
||||
}
|
||||
}
|
||||
|
||||
ret
|
||||
}
|
||||
|
||||
/// Given a u64 number, return a hashed number using this mixing function
|
||||
/// This function is used to hash an address into a more random number (used in `libafl_frida`).
|
||||
/// Mixing function: <http://mostlymangling.blogspot.com/2018/07/on-mixing-functions-in-fast-splittable.html>
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub const fn xxh3_rrmxmx_mixer(v: u64) -> u64 {
|
||||
let tmp = (v >> 32) + ((v & 0xffffffff) << 32);
|
||||
let bitflip = 0x1cad21f72c81017c ^ 0xdb979082e96dd4de;
|
||||
let mut h64 = tmp ^ bitflip;
|
||||
h64 = h64.rotate_left(49) & h64.rotate_left(24);
|
||||
h64 = h64.wrapping_mul(0x9FB21C651E98DF25);
|
||||
h64 ^= (h64 >> 35) + 8;
|
||||
h64 = h64.wrapping_mul(0x9FB21C651E98DF25);
|
||||
h64 ^= h64 >> 28;
|
||||
h64
|
||||
}
|
||||
|
||||
/// Calculates the cumulative sum for a slice, in-place.
|
||||
/// The values are useful for example for cumulative probabilities.
|
||||
///
|
||||
/// So, to give an example:
|
||||
/// ```rust
|
||||
/// # extern crate libafl_bolts;
|
||||
/// use libafl_bolts::math::calculate_cumulative_sum_in_place;
|
||||
///
|
||||
/// let mut value = [2, 4, 1, 3];
|
||||
/// calculate_cumulative_sum_in_place(&mut value);
|
||||
/// assert_eq!(&[2, 6, 7, 10], &value);
|
||||
/// ```
|
||||
pub fn calculate_cumulative_sum_in_place<T>(mut_slice: &mut [T])
|
||||
where
|
||||
T: Default + AddAssign<T> + Copy,
|
||||
{
|
||||
let mut acc = T::default();
|
||||
|
||||
for val in mut_slice {
|
||||
acc += *val;
|
||||
*val = acc;
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::{calculate_cumulative_distribution_in_place, integer_sqrt};
|
||||
|
||||
#[test]
|
||||
fn test_integer_sqrt() {
|
||||
assert_eq!(0, integer_sqrt(0));
|
||||
assert_eq!(1, integer_sqrt(1));
|
||||
assert_eq!(2, integer_sqrt(4));
|
||||
assert_eq!(10, integer_sqrt(120));
|
||||
assert_eq!(11, integer_sqrt(121));
|
||||
assert_eq!(11, integer_sqrt(128));
|
||||
assert_eq!(2_u64.pow(16) - 1, integer_sqrt(u64::from(u32::MAX)));
|
||||
assert_eq!(2_u64.pow(32) - 1, integer_sqrt(u64::MAX));
|
||||
assert_eq!(2_u64.pow(32) - 1, integer_sqrt(u64::MAX - 1));
|
||||
assert_eq!(128, integer_sqrt(128 * 128));
|
||||
assert_eq!(128, integer_sqrt((128 * 128) + 1));
|
||||
assert_eq!(128, integer_sqrt((128 * 128) + 127));
|
||||
assert_eq!(128, integer_sqrt((128 * 128) + 127));
|
||||
assert_eq!(999999, integer_sqrt((999999 * 999999) + 9));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_cdf_fails_with_invalid_probs() {
|
||||
// Distribution has to sum up to 1.
|
||||
assert!(calculate_cumulative_distribution_in_place(&mut []).is_err());
|
||||
assert!(calculate_cumulative_distribution_in_place(&mut [0.0]).is_err());
|
||||
assert!(calculate_cumulative_distribution_in_place(&mut [0.9]).is_err());
|
||||
assert!(calculate_cumulative_distribution_in_place(&mut [0.9, 0.9]).is_err());
|
||||
assert!(calculate_cumulative_distribution_in_place(&mut [f32::NAN]).is_err());
|
||||
assert!(calculate_cumulative_distribution_in_place(&mut [f32::INFINITY]).is_err());
|
||||
assert!(calculate_cumulative_distribution_in_place(&mut [f32::NEG_INFINITY]).is_err());
|
||||
|
||||
// Elements have to be between 0 and 1
|
||||
assert!(calculate_cumulative_distribution_in_place(&mut [-0.5, 0.5, 0.5]).is_err());
|
||||
|
||||
assert!(calculate_cumulative_distribution_in_place(&mut [1.0]).is_ok());
|
||||
assert!(calculate_cumulative_distribution_in_place(&mut [0.0, 1.0]).is_ok());
|
||||
assert!(calculate_cumulative_distribution_in_place(&mut [0.0, 1.0, 0.0]).is_ok());
|
||||
assert!(calculate_cumulative_distribution_in_place(&mut [0.5, 0.5]).is_ok());
|
||||
assert!(calculate_cumulative_distribution_in_place(&mut [0.2; 5]).is_ok());
|
||||
}
|
||||
}
|
@ -618,15 +618,6 @@ pub use serdeany_registry::*;
|
||||
macro_rules! create_register {
|
||||
($struct_type:ty) => {
|
||||
const _: () = {
|
||||
/// Manually register this type at a later point in time
|
||||
///
|
||||
/// # Safety
|
||||
/// This may never be called concurrently as it dereferences the `RegistryBuilder` without acquiring a lock.
|
||||
#[cfg(not(feature = "serdeany_autoreg"))]
|
||||
pub unsafe fn register() {
|
||||
$crate::serdeany::RegistryBuilder::register::<$struct_type>();
|
||||
}
|
||||
|
||||
/// Automatically register this type
|
||||
#[cfg(feature = "serdeany_autoreg")]
|
||||
#[$crate::ctor]
|
||||
@ -665,6 +656,18 @@ macro_rules! impl_serdeany {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(not(feature = "serdeany_autoreg"), miri))]
|
||||
impl< $( $lt $( : $clt $(+ $dlt )* )? ),+ > $struct_name < $( $lt ),+ > {
|
||||
|
||||
/// Manually register this type at a later point in time
|
||||
///
|
||||
/// # Safety
|
||||
/// This may never be called concurrently as it dereferences the `RegistryBuilder` without acquiring a lock.
|
||||
pub unsafe fn register() {
|
||||
$crate::serdeany::RegistryBuilder::register::<$struct_name < $( $lt ),+ >>();
|
||||
}
|
||||
}
|
||||
|
||||
$(
|
||||
$crate::create_register!($struct_name < $( $opt ),+ >);
|
||||
)*
|
||||
@ -690,6 +693,17 @@ macro_rules! impl_serdeany {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(not(feature = "serdeany_autoreg"), miri))]
|
||||
impl $struct_name {
|
||||
/// Manually register this type at a later point in time
|
||||
///
|
||||
/// # Safety
|
||||
/// This may never be called concurrently as it dereferences the `RegistryBuilder` without acquiring a lock.
|
||||
pub unsafe fn register() {
|
||||
$crate::serdeany::RegistryBuilder::register::<$struct_name>();
|
||||
}
|
||||
}
|
||||
|
||||
$crate::create_register!($struct_name);
|
||||
};
|
||||
}
|
||||
|
@ -141,13 +141,13 @@ impl ShMemId {
|
||||
/// Returns `true` if this `ShMemId` has an empty backing slice.
|
||||
/// If this is the case something went wrong, and this `ShMemId` may not be read from.
|
||||
#[must_use]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
pub const fn is_empty(&self) -> bool {
|
||||
self.id[0] == 0
|
||||
}
|
||||
|
||||
/// Get the id as a fixed-length slice
|
||||
#[must_use]
|
||||
pub fn as_array(&self) -> &[u8; 20] {
|
||||
pub const fn as_array(&self) -> &[u8; 20] {
|
||||
&self.id
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@ use std::{cell::RefCell, marker::PhantomPinned, pin::Pin, rc::Rc};
|
||||
use dynasmrt::DynasmLabelApi;
|
||||
use dynasmrt::{dynasm, DynasmApi};
|
||||
use frida_gum::{instruction_writer::InstructionWriter, stalker::StalkerOutput};
|
||||
use libafl_bolts::xxh3_rrmxmx_mixer;
|
||||
use libafl_bolts::math::xxh3_rrmxmx_mixer;
|
||||
use rangemap::RangeMap;
|
||||
|
||||
use crate::helper::FridaRuntime;
|
||||
|
@ -12,6 +12,10 @@ use crate::{
|
||||
GuestAddr,
|
||||
};
|
||||
|
||||
#[cfg_attr(
|
||||
any(not(feature = "serdeany_autoreg"), miri),
|
||||
allow(clippy::unsafe_derive_deserialize)
|
||||
)] // for SerdeAny
|
||||
#[derive(Debug, Default, Serialize, Deserialize)]
|
||||
pub struct QemuCmpsMapMetadata {
|
||||
pub map: HashMap<u64, u64>,
|
||||
|
@ -19,6 +19,10 @@ static DRCOV_IDS: Mutex<Option<Vec<u64>>> = Mutex::new(None);
|
||||
static DRCOV_MAP: Mutex<Option<HashMap<GuestAddr, u64>>> = Mutex::new(None);
|
||||
static DRCOV_LENGTHS: Mutex<Option<HashMap<GuestAddr, GuestUsize>>> = Mutex::new(None);
|
||||
|
||||
#[cfg_attr(
|
||||
any(not(feature = "serdeany_autoreg"), miri),
|
||||
allow(clippy::unsafe_derive_deserialize)
|
||||
)] // for SerdeAny
|
||||
#[derive(Debug, Default, Serialize, Deserialize)]
|
||||
pub struct QemuDrCovMetadata {
|
||||
pub current_id: u64,
|
||||
|
@ -14,6 +14,10 @@ use crate::{
|
||||
hooks::QemuHooks,
|
||||
};
|
||||
|
||||
#[cfg_attr(
|
||||
any(not(feature = "serdeany_autoreg"), miri),
|
||||
allow(clippy::unsafe_derive_deserialize)
|
||||
)] // for SerdeAny
|
||||
#[derive(Debug, Default, Serialize, Deserialize)]
|
||||
pub struct QemuEdgesMapMetadata {
|
||||
pub map: HashMap<(GuestAddr, GuestAddr), u64>,
|
||||
|
Loading…
x
Reference in New Issue
Block a user